From a6cbe07912b451cffdb1d0f74c7adba2801e6c77 Mon Sep 17 00:00:00 2001 From: Seb James Date: Wed, 4 Mar 2026 14:45:41 +0000 Subject: [PATCH 001/106] The changes required to compile one program with modular maths --- CMakeLists.txt | 4 ++-- examples/CMakeLists.txt | 38 +++++++++++++++++++++++++++++++++++++ examples/helloworld.cpp | 2 ++ maths | 2 +- mplot/CoordArrows.h | 2 +- mplot/NavMesh.h | 11 ++++++----- mplot/RodVisual.h | 4 ++-- mplot/VisualBase.h | 8 ++++---- mplot/VisualCommon.h | 10 ++++++---- mplot/VisualModelBase.h | 17 +++++++++-------- mplot/VisualTextModelBase.h | 7 ++++--- mplot/gl/ssbo_mx.h | 7 ++++--- 12 files changed, 79 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8280c82f..9e761e13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 3.14) -project(mathplot) +cmake_minimum_required(VERSION 3.28.5) +project(mathplot LANGUAGES CXX) # Note that the project version is encoded in mplot/version.h and not in this CMakeLists.txt message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}") diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index cb4592b9..1013bbdf 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -23,6 +23,32 @@ endif() # All #includes in test programs have to be #include include_directories(BEFORE ${PROJECT_SOURCE_DIR}) +# Each C++ module file has to be listed here (as they don't have a .cppm or .ixx file suffix) +set_source_files_properties ( + ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/random + ${PROJECT_SOURCE_DIR}/maths/sm/vec + ${PROJECT_SOURCE_DIR}/maths/sm/vvec + ${PROJECT_SOURCE_DIR}/maths/sm/scale + ${PROJECT_SOURCE_DIR}/maths/sm/hdfdata + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/hex + ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord + ${PROJECT_SOURCE_DIR}/maths/sm/bezcurve + ${PROJECT_SOURCE_DIR}/maths/sm/winder + ${PROJECT_SOURCE_DIR}/maths/sm/bootstrap + ${PROJECT_SOURCE_DIR}/maths/sm/grid + ${PROJECT_SOURCE_DIR}/maths/sm/algo + ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex + ${PROJECT_SOURCE_DIR}/maths/sm/histo + ${PROJECT_SOURCE_DIR}/maths/sm/boxfilter + ${PROJECT_SOURCE_DIR}/maths/sm/config + ${PROJECT_SOURCE_DIR}/maths/sm/geometry + ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/flags + PROPERTIES LANGUAGE CXX) + # Screenshots used in the documentation/reference website if(BUILD_DOC_SCREENSHOTS) add_subdirectory(docs) @@ -147,6 +173,18 @@ if(ARMADILLO_FOUND) endif(ARMADILLO_FOUND) add_executable(helloworld helloworld.cpp) +target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES + ${PROJECT_SOURCE_DIR}/maths/sm/flags + ${PROJECT_SOURCE_DIR}/maths/sm/algo + ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/random + ${PROJECT_SOURCE_DIR}/maths/sm/vec + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/geometry + ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/vvec) target_link_libraries(helloworld OpenGL::GL glfw Freetype::Freetype) add_executable(helloversion helloversion.cpp) diff --git a/examples/helloworld.cpp b/examples/helloworld.cpp index c0fd0bad..dc5e4750 100644 --- a/examples/helloworld.cpp +++ b/examples/helloworld.cpp @@ -6,3 +6,5 @@ int main() v.keepOpen(); return 0; } + + diff --git a/maths b/maths index ab7b1595..df0ff390 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit ab7b1595ee6f2cb44063a4ee1c736f5ac9a1a7e5 +Subproject commit df0ff390c8bcb19f00ccab6b01d47d69acea22e7 diff --git a/mplot/CoordArrows.h b/mplot/CoordArrows.h index c64877f9..c0137a30 100644 --- a/mplot/CoordArrows.h +++ b/mplot/CoordArrows.h @@ -9,7 +9,7 @@ #pragma once #include -#include +import sm.vec; #include #include #include diff --git a/mplot/NavMesh.h b/mplot/NavMesh.h index 5a103745..7299fc93 100644 --- a/mplot/NavMesh.h +++ b/mplot/NavMesh.h @@ -20,13 +20,14 @@ #include #include -#include -#include -#include -#include -#include #include +import sm.vec; +import sm.vvec; +import sm.flags; +import sm.mat; +import sm.geometry; + namespace mplot { namespace mesh diff --git a/mplot/RodVisual.h b/mplot/RodVisual.h index c15a2738..224c6218 100644 --- a/mplot/RodVisual.h +++ b/mplot/RodVisual.h @@ -1,9 +1,9 @@ #pragma once +#include #include -#include +import sm.vec; #include -#include namespace mplot { diff --git a/mplot/VisualBase.h b/mplot/VisualBase.h index b9ba746d..d22b36ae 100644 --- a/mplot/VisualBase.h +++ b/mplot/VisualBase.h @@ -18,10 +18,10 @@ #include #include -#include -#include -#include -#include +import sm.flags; +import sm.quaternion; +import sm.mat; +import sm.vec; #include #include diff --git a/mplot/VisualCommon.h b/mplot/VisualCommon.h index 38d1dd07..49248bb8 100644 --- a/mplot/VisualCommon.h +++ b/mplot/VisualCommon.h @@ -11,10 +11,12 @@ #include #include #include -#include -#include -#include -#include + +import sm.vec; +import sm.range; +import sm.vvec; +import sm.mat; + #include #include diff --git a/mplot/VisualModelBase.h b/mplot/VisualModelBase.h index 2dfcdefd..2f971470 100644 --- a/mplot/VisualModelBase.h +++ b/mplot/VisualModelBase.h @@ -35,16 +35,17 @@ #include -#include -#include -#include -#include -#include -#include #include #include -#include -#include + +import sm.geometry_polyhedra; +import sm.quaternion; +import sm.mat; +import sm.vec; +import sm.vvec; +import sm.range; +import sm.algo; +import sm.flags; #include #include diff --git a/mplot/VisualTextModelBase.h b/mplot/VisualTextModelBase.h index a834faac..0b6abcad 100644 --- a/mplot/VisualTextModelBase.h +++ b/mplot/VisualTextModelBase.h @@ -16,12 +16,13 @@ #include #include #include +#include #include -#include -#include -#include +import sm.quaternion; +import sm.mat; +import sm.vec; #include #include diff --git a/mplot/gl/ssbo_mx.h b/mplot/gl/ssbo_mx.h index 814a5caa..209b688c 100644 --- a/mplot/gl/ssbo_mx.h +++ b/mplot/gl/ssbo_mx.h @@ -10,11 +10,12 @@ */ #include -#include -#include -#include #include +import sm.vec; +import sm.vvec; +import sm.range; + namespace mplot::gl { // An SSBO and its data From f9a38ad9f903f3c1a36181a0a1783688bd88b119 Mon Sep 17 00:00:00 2001 From: Seb James Date: Wed, 4 Mar 2026 15:04:08 +0000 Subject: [PATCH 002/106] Removes some unnecessary headers --- mplot/VisualTextModelBase.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/mplot/VisualTextModelBase.h b/mplot/VisualTextModelBase.h index 0b6abcad..fa29fa0b 100644 --- a/mplot/VisualTextModelBase.h +++ b/mplot/VisualTextModelBase.h @@ -13,9 +13,6 @@ #include #include #include -#include -#include -#include #include #include From 447a0159906dec8765c9e98e0a3e155292cb440a Mon Sep 17 00:00:00 2001 From: Seb James Date: Wed, 4 Mar 2026 15:07:39 +0000 Subject: [PATCH 003/106] gcc 14 or probably higher --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e761e13..e17ea207 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}") message(STATUS " (This can be changed with `cmake -DCMAKE_INSTALL_PREFIX=/some/place`") # -# The base C++ version in mathplot is current C++-17 but I am considering C++20 or 23 +# We're firmly at C++20. # set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -44,9 +44,9 @@ else() set(CMAKE_CXX_FLAGS "-Wall -g -std=c++20 -xHOST -O3") else() # GCC or Clang if(CMAKE_CXX_COMPILER_ID MATCHES GNU) - # Add compiler version check, to ensure gcc is version 11 or later. - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11) - message(FATAL_ERROR "GCC version must be at least 11") + # Add compiler version check, to ensure gcc is version 14? 15? or later. + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14) + message(FATAL_ERROR "GCC version must be at least 14") else() message(STATUS "GCC version ${CMAKE_CXX_COMPILER_VERSION} OK!") endif() From 005cce3f1c31bb6403f2190c3a4eddcd46321f70 Mon Sep 17 00:00:00 2001 From: Seb James Date: Wed, 4 Mar 2026 23:50:54 +0000 Subject: [PATCH 004/106] Attempting to compile any VIsual other than CoordArrows causes circular dependency error?! --- doxygen/Doxyfile.in | 8 ++++---- doxygen/Doxyfile_local.in | 4 ++-- examples/CMakeLists.txt | 30 +++++++++++++++++++++++++++++- examples/grid_simple.cpp | 4 ++-- examples/rod.cpp | 4 ++-- maths | 2 +- mplot/GridVisual.h | 6 +++--- mplot/RodVisual.h | 3 ++- mplot/VisualBase.h | 1 + mplot/VisualDataModel.h | 11 +++++++---- mplot/VisualResources.h | 2 ++ mplot/VisualTextModel.h | 2 ++ mplot/VisualTextModelBase.h | 10 +++++----- 13 files changed, 62 insertions(+), 25 deletions(-) diff --git a/doxygen/Doxyfile.in b/doxygen/Doxyfile.in index e5e06ba9..987370c1 100644 --- a/doxygen/Doxyfile.in +++ b/doxygen/Doxyfile.in @@ -3,7 +3,7 @@ #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -PROJECT_NAME = morphologica +PROJECT_NAME = mathplot PROJECT_NUMBER = git main OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/doc_doxygen/ OUTPUT_LANGUAGE = English @@ -63,11 +63,11 @@ WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- -INPUT = ../morph ../morph/nn ../morph/bn ../README.md ../morph/gl ../morph/qt ../morph/wx ../morph/linuxos +INPUT = ../mplot ../mplot/compoundray ../mplot/fonts ../README.md ../mplot/fps ../mplot/gl ../mplot/glad ../mplot/healpix ../mplot/jcvoronoi ../mplot/qt ../mplot/wx ../maths/sm USE_MDFILE_AS_MAINPAGE = README.md -FILE_PATTERNS = *.h +FILE_PATTERNS = * RECURSIVE = NO -EXCLUDE = ../morph/nlohmann ../morph/rapidxml.hpp ../morph/rapidxml_iterators.hpp ../morph/rapidxml_print.hpp ../morph/rapidxml_utils.hpp ../morph/lodepng.h +EXCLUDE = ../mplot/nlohmann EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXAMPLE_PATH = diff --git a/doxygen/Doxyfile_local.in b/doxygen/Doxyfile_local.in index 5f3859d3..ed55d125 100644 --- a/doxygen/Doxyfile_local.in +++ b/doxygen/Doxyfile_local.in @@ -3,7 +3,7 @@ #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -PROJECT_NAME = morphologica +PROJECT_NAME = mathplot PROJECT_NUMBER = @VERSION@ OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/doc_doxygen/ OUTPUT_LANGUAGE = English @@ -63,7 +63,7 @@ WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- -INPUT = @CMAKE_CURRENT_SOURCE_DIR@/morph/ @CMAKE_CURRENT_SOURCE_DIR@/tests @CMAKE_CURRENT_SOURCE_DIR@/README.md +INPUT = @CMAKE_CURRENT_SOURCE_DIR@/mplot/ @CMAKE_CURRENT_SOURCE_DIR@/tests @CMAKE_CURRENT_SOURCE_DIR@/README.md USE_MDFILE_AS_MAINPAGE = @CMAKE_CURRENT_SOURCE_DIR@/README.md FILE_PATTERNS = *.h RECURSIVE = NO diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 1013bbdf..1d2c8d68 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -47,7 +47,9 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/maths/sm/geometry ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra ${PROJECT_SOURCE_DIR}/maths/sm/flags - PROPERTIES LANGUAGE CXX) + ${PROJECT_SOURCE_DIR}/maths/sm/centroid + PROPERTIES LANGUAGE CXX +) # Screenshots used in the documentation/reference website if(BUILD_DOC_SCREENSHOTS) @@ -195,6 +197,21 @@ target_link_libraries(myvisual OpenGL::GL glfw Freetype::Freetype) # mplot::Grid is runtime-configured add_executable(grid_simple grid_simple.cpp) +target_sources(grid_simple PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES + ${PROJECT_SOURCE_DIR}/maths/sm/flags + ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/random + ${PROJECT_SOURCE_DIR}/maths/sm/vec + ${PROJECT_SOURCE_DIR}/maths/sm/algo + ${PROJECT_SOURCE_DIR}/maths/sm/vvec + ${PROJECT_SOURCE_DIR}/maths/sm/centroid + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/geometry + ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/grid +) target_link_libraries(grid_simple OpenGL::GL glfw Freetype::Freetype) add_executable(grid_flat_dynamic grid_flat_dynamic.cpp) @@ -373,6 +390,17 @@ add_executable(threewindows threewindows.cpp) target_link_libraries(threewindows OpenGL::GL glfw Freetype::Freetype) add_executable(rod rod.cpp) +target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES + ${PROJECT_SOURCE_DIR}/maths/sm/flags + ${PROJECT_SOURCE_DIR}/maths/sm/algo + ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/random + ${PROJECT_SOURCE_DIR}/maths/sm/vec + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/geometry + ${PROJECT_SOURCE_DIR}/maths/sm/vvec) target_link_libraries(rod OpenGL::GL glfw Freetype::Freetype) add_executable(rod_with_normals rod_with_normals.cpp) diff --git a/examples/grid_simple.cpp b/examples/grid_simple.cpp index 1e8d43cf..71924883 100644 --- a/examples/grid_simple.cpp +++ b/examples/grid_simple.cpp @@ -6,8 +6,8 @@ #include #include -#include -#include +import sm.vec; +import sm.grid; #include #include diff --git a/examples/rod.cpp b/examples/rod.cpp index 8df0e841..49de6fdb 100644 --- a/examples/rod.cpp +++ b/examples/rod.cpp @@ -8,12 +8,12 @@ #include #include -#include - #include #include #include +import sm.vec; + int main() { int rtn = -1; diff --git a/maths b/maths index df0ff390..444007b0 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit df0ff390c8bcb19f00ccab6b01d47d69acea22e7 +Subproject commit 444007b080a50f6c519992f4c9c01680c53c44b0 diff --git a/mplot/GridVisual.h b/mplot/GridVisual.h index 1c6056a2..fc04dfe3 100644 --- a/mplot/GridVisual.h +++ b/mplot/GridVisual.h @@ -5,9 +5,9 @@ #include #include -#include -#include -#include +import sm.grid; +import sm.vec; +import sm.flags; #include #include diff --git a/mplot/RodVisual.h b/mplot/RodVisual.h index 224c6218..15e3567d 100644 --- a/mplot/RodVisual.h +++ b/mplot/RodVisual.h @@ -2,9 +2,10 @@ #include #include -import sm.vec; #include +import sm.vec; + namespace mplot { //! This class creates the vertices for a cylindrical 'rod' in a 3D scene. diff --git a/mplot/VisualBase.h b/mplot/VisualBase.h index d22b36ae..e334162a 100644 --- a/mplot/VisualBase.h +++ b/mplot/VisualBase.h @@ -18,6 +18,7 @@ #include #include +import sm.range; import sm.flags; import sm.quaternion; import sm.mat; diff --git a/mplot/VisualDataModel.h b/mplot/VisualDataModel.h index fe3d7abd..34754598 100644 --- a/mplot/VisualDataModel.h +++ b/mplot/VisualDataModel.h @@ -5,13 +5,16 @@ #include #include -#include -#include -#include -#include + +import sm.vec; +import sm.vvec; +import sm.scale; +import sm.centroid; + #include #include + namespace mplot { //! VisualDataModel implementation base class containing common functionality - all the diff --git a/mplot/VisualResources.h b/mplot/VisualResources.h index 0fb3d905..94e414e9 100644 --- a/mplot/VisualResources.h +++ b/mplot/VisualResources.h @@ -22,6 +22,8 @@ #include #include +import sm.vec; + namespace mplot { // Pointers to mplot::VisualBase are used to index font faces diff --git a/mplot/VisualTextModel.h b/mplot/VisualTextModel.h index c0adcea5..ef961635 100644 --- a/mplot/VisualTextModel.h +++ b/mplot/VisualTextModel.h @@ -29,6 +29,8 @@ #include #include +import sm.vec; + namespace mplot { //! Forward declaration of a VisualBase class diff --git a/mplot/VisualTextModelBase.h b/mplot/VisualTextModelBase.h index fa29fa0b..59019d62 100644 --- a/mplot/VisualTextModelBase.h +++ b/mplot/VisualTextModelBase.h @@ -17,17 +17,17 @@ #include -import sm.quaternion; -import sm.mat; -import sm.vec; -#include - #include #include #include #include #include +#include +import sm.quaternion; +import sm.mat; +import sm.vec; + namespace mplot { //! Forward declaration of a VisualBase class From 7966abdbd85dc1b134e550d068281b28c6f9ab7d Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 5 Mar 2026 00:12:24 +0000 Subject: [PATCH 005/106] Minor change in maths --- maths | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths b/maths index 444007b0..d8913009 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit 444007b080a50f6c519992f4c9c01680c53c44b0 +Subproject commit d8913009af5d950facc1d8dceb0d02da8f48edcc From 3ce2211484cef530b45edc2f757bcf0e9723f095 Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 5 Mar 2026 12:35:35 +0000 Subject: [PATCH 006/106] Updates before batch upgrades --- examples/CMakeLists.txt | 183 +++++++++++++++++++++++---------------- examples/grid_simple.cpp | 4 +- examples/rod.cpp | 1 + examples/showcase.cpp | 5 +- maths | 2 +- 5 files changed, 113 insertions(+), 82 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 1d2c8d68..1a4197ef 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,25 +1,3 @@ -# Shader compute examples. Not supported on Apple, which is limited to -# OpenGL 4.1 or Windows because I want to keep the GL header inclusion -# simple on these examples. -if(NOT APPLE AND NOT WIN32) - add_subdirectory(gl_compute) -endif() - -# Examples showing how to use mathplot with Qt. Compiled only if -# find_package found Qt5 -if(Qt5_FOUND) - add_subdirectory(qt) -endif() - -# Disabled as haven't figured out a GL multi-context scheme for wx windows -#if(wxWidgets_FOUND) -# add_subdirectory(wx) -#endif() - -if (OpenGL_EGL_FOUND) - add_subdirectory(pi) -endif() - # All #includes in test programs have to be #include include_directories(BEFORE ${PROJECT_SOURCE_DIR}) @@ -51,10 +29,82 @@ set_source_files_properties ( PROPERTIES LANGUAGE CXX ) -# Screenshots used in the documentation/reference website -if(BUILD_DOC_SCREENSHOTS) - add_subdirectory(docs) -endif() +add_executable(helloworld helloworld.cpp) +target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES + ${PROJECT_SOURCE_DIR}/maths/sm/flags + ${PROJECT_SOURCE_DIR}/maths/sm/algo + ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/random + ${PROJECT_SOURCE_DIR}/maths/sm/vec + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/geometry + ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/vvec) +target_link_libraries(helloworld OpenGL::GL glfw Freetype::Freetype) + +add_executable(rod rod.cpp) +target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES + ${PROJECT_SOURCE_DIR}/maths/sm/flags + ${PROJECT_SOURCE_DIR}/maths/sm/algo + ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/random + ${PROJECT_SOURCE_DIR}/maths/sm/vec + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/geometry + ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/vvec) +target_link_libraries(rod OpenGL::GL glfw Freetype::Freetype) + +# mplot::Grid is runtime-configured +add_executable(grid_simple grid_simple.cpp) +target_sources(grid_simple PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES + ${PROJECT_SOURCE_DIR}/maths/sm/flags + ${PROJECT_SOURCE_DIR}/maths/sm/scale + ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/random + ${PROJECT_SOURCE_DIR}/maths/sm/vec + ${PROJECT_SOURCE_DIR}/maths/sm/algo + ${PROJECT_SOURCE_DIR}/maths/sm/vvec + ${PROJECT_SOURCE_DIR}/maths/sm/centroid + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/geometry + ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/grid +) +target_link_libraries(grid_simple OpenGL::GL glfw Freetype::Freetype) + +# +# Any example that uses sm::hexgrid or sm::cartgrid requires +# libarmadillo (because the classes use sm::BezCurve). +# +if(ARMADILLO_FOUND) + add_executable(showcase showcase.cpp) + target_sources(showcase PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES + ${PROJECT_SOURCE_DIR}/maths/sm/flags + ${PROJECT_SOURCE_DIR}/maths/sm/scale + ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/random + ${PROJECT_SOURCE_DIR}/maths/sm/vec + ${PROJECT_SOURCE_DIR}/maths/sm/algo + ${PROJECT_SOURCE_DIR}/maths/sm/vvec + ${PROJECT_SOURCE_DIR}/maths/sm/centroid + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/geometry + ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/grid + ) + target_link_libraries(showcase OpenGL::GL glfw Freetype::Freetype) +endif(ARMADILLO_FOUND) + +if(0) # During development # # Any example that uses sm::hexgrid or sm::cartgrid requires @@ -169,51 +219,14 @@ if(ARMADILLO_FOUND) endif() endif(NOT APPLE) - add_executable(showcase showcase.cpp) - target_link_libraries(showcase OpenGL::GL glfw Freetype::Freetype) - endif(ARMADILLO_FOUND) -add_executable(helloworld helloworld.cpp) -target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES - ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/range - ${PROJECT_SOURCE_DIR}/maths/sm/random - ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion - ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/geometry - ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra - ${PROJECT_SOURCE_DIR}/maths/sm/vvec) -target_link_libraries(helloworld OpenGL::GL glfw Freetype::Freetype) - add_executable(helloversion helloversion.cpp) target_link_libraries(helloversion OpenGL::GL glfw Freetype::Freetype) add_executable(myvisual myvisual.cpp) target_link_libraries(myvisual OpenGL::GL glfw Freetype::Freetype) -# mplot::Grid is runtime-configured -add_executable(grid_simple grid_simple.cpp) -target_sources(grid_simple PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES - ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/range - ${PROJECT_SOURCE_DIR}/maths/sm/random - ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/vvec - ${PROJECT_SOURCE_DIR}/maths/sm/centroid - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion - ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/geometry - ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra - ${PROJECT_SOURCE_DIR}/maths/sm/grid -) -target_link_libraries(grid_simple OpenGL::GL glfw Freetype::Freetype) - add_executable(grid_flat_dynamic grid_flat_dynamic.cpp) target_link_libraries(grid_flat_dynamic OpenGL::GL glfw Freetype::Freetype) @@ -389,20 +402,6 @@ target_link_libraries(twowindows_mutex OpenGL::GL glfw Freetype::Freetype) add_executable(threewindows threewindows.cpp) target_link_libraries(threewindows OpenGL::GL glfw Freetype::Freetype) -add_executable(rod rod.cpp) -target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES - ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/range - ${PROJECT_SOURCE_DIR}/maths/sm/random - ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion - ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/geometry - ${PROJECT_SOURCE_DIR}/maths/sm/vvec) -target_link_libraries(rod OpenGL::GL glfw Freetype::Freetype) - add_executable(rod_with_normals rod_with_normals.cpp) target_link_libraries(rod_with_normals OpenGL::GL glfw Freetype::Freetype) @@ -624,3 +623,33 @@ endif() add_executable(trace_boundary trace_boundary.cpp) target_link_libraries(trace_boundary OpenGL::GL glfw Freetype::Freetype) + +# Shader compute examples. Not supported on Apple, which is limited to +# OpenGL 4.1 or Windows because I want to keep the GL header inclusion +# simple on these examples. +if(NOT APPLE AND NOT WIN32) + add_subdirectory(gl_compute) +endif() + +# Examples showing how to use mathplot with Qt. Compiled only if +# find_package found Qt5 +if(Qt5_FOUND) + add_subdirectory(qt) +endif() + +# Disabled as haven't figured out a GL multi-context scheme for wx windows +#if(wxWidgets_FOUND) +# add_subdirectory(wx) +#endif() + +if (OpenGL_EGL_FOUND) + add_subdirectory(pi) +endif() + + +# Screenshots used in the documentation/reference website +if(BUILD_DOC_SCREENSHOTS) + add_subdirectory(docs) +endif() + +endif(0) diff --git a/examples/grid_simple.cpp b/examples/grid_simple.cpp index 71924883..f730e44a 100644 --- a/examples/grid_simple.cpp +++ b/examples/grid_simple.cpp @@ -10,8 +10,8 @@ import sm.vec; import sm.grid; #include -#include -#include +#include // import mplot.core; +#include // import mplot.gridvisual; int main() { diff --git a/examples/rod.cpp b/examples/rod.cpp index 49de6fdb..5189f1ac 100644 --- a/examples/rod.cpp +++ b/examples/rod.cpp @@ -9,6 +9,7 @@ #include #include + #include #include diff --git a/examples/showcase.cpp b/examples/showcase.cpp index d54a41ce..823cc6d3 100644 --- a/examples/showcase.cpp +++ b/examples/showcase.cpp @@ -1,9 +1,10 @@ // A showcase of different visual models -#include +import sm.vvec; +import sm.grid; + #include #include -#include #include #include diff --git a/maths b/maths index d8913009..9297841f 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit d8913009af5d950facc1d8dceb0d02da8f48edcc +Subproject commit 9297841f8150d4a587a18b64e1f5dba7b87698ba From fa82e1370e035ab0557d09eef2c87ce8567297a2 Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 5 Mar 2026 12:50:53 +0000 Subject: [PATCH 007/106] Converts to imports --- examples/CMakeLists.txt | 1 - mplot/CartGridVisual.h | 2 +- mplot/ColourBarVisual.h | 6 +++--- mplot/ColourMap.h | 4 ++-- mplot/ConeVisual.h | 2 +- mplot/ConfigVisual.h | 2 +- mplot/CurvyTellyVisual.h | 4 ++-- mplot/CyclicColourVisual.h | 2 +- mplot/DatasetStyle.h | 4 ++-- mplot/GeodesicVisual.h | 8 ++++---- mplot/GeodesicVisualCE.h | 2 +- mplot/GraphVisual.h | 14 +++++++------- mplot/GratingVisual.h | 4 ++-- mplot/HSVWheelVisual.h | 2 +- mplot/HealpixVisual.h | 6 +++--- mplot/HexGridVisual.h | 6 +++--- mplot/IcosaVisual.h | 2 +- mplot/InstancedScatterVisual.h | 2 +- mplot/LengthscaleVisual.h | 6 +++--- mplot/NormalsVisual.h | 6 +++--- mplot/PointRowsMeshVisual.h | 4 ++-- mplot/PointRowsVisual.h | 4 ++-- mplot/PolarVisual.h | 2 +- mplot/PolygonVisual.h | 2 +- mplot/QuadsMeshVisual.h | 4 ++-- mplot/QuadsVisual.h | 4 ++-- mplot/QuiverVisual.h | 6 +++--- mplot/RectangleVisual.h | 4 ++-- mplot/RhomboVisual.h | 2 +- mplot/RingVisual.h | 2 +- mplot/ScatterVisual.h | 2 +- mplot/SphereVisual.h | 2 +- mplot/SphericalProjectionVisual.h | 6 +++--- mplot/TriFrameVisual.h | 2 +- mplot/TriangleVisual.h | 2 +- mplot/TriaxesVisual.h | 6 +++--- mplot/TxtVisual.h | 2 +- mplot/VectorVisual.h | 2 +- mplot/VerticesVisual.h | 6 +++--- mplot/VoronoiVisual.h | 10 +++++----- mplot/compoundray/EyeVisual.h | 10 +++++----- mplot/compoundray/interop.h | 4 ++-- mplot/gl/compute_shaderprog.h | 4 ++-- mplot/gl/ssbo_nomx.h | 6 +++--- mplot/gl/texture.h | 2 +- mplot/graphing.h | 6 +++--- mplot/jcvoronoi/jc_voronoi.h | 6 +++--- mplot/loadpng.h | 4 ++-- 48 files changed, 100 insertions(+), 101 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 1a4197ef..7427ee53 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -21,7 +21,6 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex ${PROJECT_SOURCE_DIR}/maths/sm/histo ${PROJECT_SOURCE_DIR}/maths/sm/boxfilter - ${PROJECT_SOURCE_DIR}/maths/sm/config ${PROJECT_SOURCE_DIR}/maths/sm/geometry ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra ${PROJECT_SOURCE_DIR}/maths/sm/flags diff --git a/mplot/CartGridVisual.h b/mplot/CartGridVisual.h index f9344fc9..909743ec 100644 --- a/mplot/CartGridVisual.h +++ b/mplot/CartGridVisual.h @@ -5,7 +5,7 @@ #include #include -#include +import sm.vec; #include #include diff --git a/mplot/ColourBarVisual.h b/mplot/ColourBarVisual.h index 7e1537d7..bbf39905 100644 --- a/mplot/ColourBarVisual.h +++ b/mplot/ColourBarVisual.h @@ -4,9 +4,9 @@ #pragma once -#include -#include -#include +import sm.range; +import sm.scale; +import sm.vec; #include #include diff --git a/mplot/ColourMap.h b/mplot/ColourMap.h index 78f4b8a2..0ec2404d 100644 --- a/mplot/ColourMap.h +++ b/mplot/ColourMap.h @@ -11,9 +11,9 @@ #include #include -#include +import sm.vec; #include -#include +import sm.flags; #include namespace mplot diff --git a/mplot/ConeVisual.h b/mplot/ConeVisual.h index abe45ca6..61077664 100644 --- a/mplot/ConeVisual.h +++ b/mplot/ConeVisual.h @@ -5,7 +5,7 @@ */ #include -#include +import sm.vec; #include #include diff --git a/mplot/ConfigVisual.h b/mplot/ConfigVisual.h index 6751df0e..c5411b3a 100644 --- a/mplot/ConfigVisual.h +++ b/mplot/ConfigVisual.h @@ -10,7 +10,7 @@ #include #include -#include +import sm.vec; #include #include diff --git a/mplot/CurvyTellyVisual.h b/mplot/CurvyTellyVisual.h index e00106b5..b3eeb2f1 100644 --- a/mplot/CurvyTellyVisual.h +++ b/mplot/CurvyTellyVisual.h @@ -2,8 +2,8 @@ #include #include -#include -#include +import sm.vec; +import sm.grid; #include namespace mplot diff --git a/mplot/CyclicColourVisual.h b/mplot/CyclicColourVisual.h index 85eac170..102c12b6 100644 --- a/mplot/CyclicColourVisual.h +++ b/mplot/CyclicColourVisual.h @@ -7,7 +7,7 @@ #include #include -#include +import sm.vec; #include #include diff --git a/mplot/DatasetStyle.h b/mplot/DatasetStyle.h index 731f0c80..aef5eb8d 100644 --- a/mplot/DatasetStyle.h +++ b/mplot/DatasetStyle.h @@ -2,8 +2,8 @@ #include #include -#include -#include +import sm.vec; +import sm.flags; #include #include #include diff --git a/mplot/GeodesicVisual.h b/mplot/GeodesicVisual.h index d6b6ea18..cc9704bf 100644 --- a/mplot/GeodesicVisual.h +++ b/mplot/GeodesicVisual.h @@ -1,10 +1,10 @@ #pragma once #include -#include -#include -#include -#include +import sm.vec; +import sm.vvec; +import sm.scale; +import sm.geometry; #include #include diff --git a/mplot/GeodesicVisualCE.h b/mplot/GeodesicVisualCE.h index 37d62696..2f1e0465 100644 --- a/mplot/GeodesicVisualCE.h +++ b/mplot/GeodesicVisualCE.h @@ -1,7 +1,7 @@ #pragma once #include -#include +import sm.vec; #include #include diff --git a/mplot/GraphVisual.h b/mplot/GraphVisual.h index 19bb6519..de945423 100644 --- a/mplot/GraphVisual.h +++ b/mplot/GraphVisual.h @@ -16,13 +16,13 @@ #include #include -#include -#include -#include -#include -#include -#include -#include +import sm.scale; +import sm.range; +import sm.vec; +import sm.vvec; +import sm.quaternion; +import sm.histo; +import sm.grid; #include #include diff --git a/mplot/GratingVisual.h b/mplot/GratingVisual.h index 03833421..93fc4316 100644 --- a/mplot/GratingVisual.h +++ b/mplot/GratingVisual.h @@ -13,8 +13,8 @@ #include #include -#include -#include +import sm.vec; +import sm.geometry; #include #include diff --git a/mplot/HSVWheelVisual.h b/mplot/HSVWheelVisual.h index 561d4346..813d47ce 100644 --- a/mplot/HSVWheelVisual.h +++ b/mplot/HSVWheelVisual.h @@ -5,7 +5,7 @@ #pragma once #include -#include +import sm.vec; #include #include diff --git a/mplot/HealpixVisual.h b/mplot/HealpixVisual.h index d5974969..b2b23dee 100644 --- a/mplot/HealpixVisual.h +++ b/mplot/HealpixVisual.h @@ -1,9 +1,9 @@ #pragma once #include -#include -#include -#include +import sm.scale; +import sm.vec; +import sm.vvec; #include #include #include diff --git a/mplot/HexGridVisual.h b/mplot/HexGridVisual.h index c2e001ee..7be96a74 100644 --- a/mplot/HexGridVisual.h +++ b/mplot/HexGridVisual.h @@ -3,10 +3,10 @@ #include #include #include -#include -#include +import sm.vec; +import sm.vvec; #include -#include +import sm.scale; #include #include #include diff --git a/mplot/IcosaVisual.h b/mplot/IcosaVisual.h index fd293658..036e8aa1 100644 --- a/mplot/IcosaVisual.h +++ b/mplot/IcosaVisual.h @@ -2,7 +2,7 @@ #include #include -#include +import sm.vec; #include namespace mplot diff --git a/mplot/InstancedScatterVisual.h b/mplot/InstancedScatterVisual.h index 009fda02..2cdd6680 100644 --- a/mplot/InstancedScatterVisual.h +++ b/mplot/InstancedScatterVisual.h @@ -9,7 +9,7 @@ #include #include #include -#include +import sm.vec; #include #include #include diff --git a/mplot/LengthscaleVisual.h b/mplot/LengthscaleVisual.h index 02d86162..d38865c9 100644 --- a/mplot/LengthscaleVisual.h +++ b/mplot/LengthscaleVisual.h @@ -7,9 +7,9 @@ #include #include -#include -#include -#include +import sm.vec; +import sm.scale; +import sm.quaternion; #include diff --git a/mplot/NormalsVisual.h b/mplot/NormalsVisual.h index 59356caf..c158b855 100644 --- a/mplot/NormalsVisual.h +++ b/mplot/NormalsVisual.h @@ -5,9 +5,9 @@ */ #include -#include -#include -#include +import sm.vec; +import sm.mat; +import sm.flags; #include #include diff --git a/mplot/PointRowsMeshVisual.h b/mplot/PointRowsMeshVisual.h index 6a31f474..a7f91cd5 100644 --- a/mplot/PointRowsMeshVisual.h +++ b/mplot/PointRowsMeshVisual.h @@ -5,8 +5,8 @@ #include #include -#include -#include +import sm.scale; +import sm.vec; #include #include diff --git a/mplot/PointRowsVisual.h b/mplot/PointRowsVisual.h index 492c3866..24940bec 100644 --- a/mplot/PointRowsVisual.h +++ b/mplot/PointRowsVisual.h @@ -5,8 +5,8 @@ #include #include -#include -#include +import sm.scale; +import sm.vec; #include #include diff --git a/mplot/PolarVisual.h b/mplot/PolarVisual.h index dd37132a..0c0b4c18 100644 --- a/mplot/PolarVisual.h +++ b/mplot/PolarVisual.h @@ -5,7 +5,7 @@ #pragma once #include -#include +import sm.vec; #include #include diff --git a/mplot/PolygonVisual.h b/mplot/PolygonVisual.h index 360e37b5..e0f4e129 100644 --- a/mplot/PolygonVisual.h +++ b/mplot/PolygonVisual.h @@ -1,7 +1,7 @@ #pragma once #include -#include +import sm.vec; #include namespace mplot diff --git a/mplot/QuadsMeshVisual.h b/mplot/QuadsMeshVisual.h index 6d751be6..1bf28835 100644 --- a/mplot/QuadsMeshVisual.h +++ b/mplot/QuadsMeshVisual.h @@ -7,8 +7,8 @@ #include #include -#include -#include +import sm.scale; +import sm.vec; #include #include diff --git a/mplot/QuadsVisual.h b/mplot/QuadsVisual.h index d4e3c417..07c1c8a2 100644 --- a/mplot/QuadsVisual.h +++ b/mplot/QuadsVisual.h @@ -6,8 +6,8 @@ #include #include -#include -#include +import sm.scale; +import sm.vec; #include #include diff --git a/mplot/QuiverVisual.h b/mplot/QuiverVisual.h index 8e0b4454..bc59555e 100644 --- a/mplot/QuiverVisual.h +++ b/mplot/QuiverVisual.h @@ -6,9 +6,9 @@ #include #include -#include -#include -#include +import sm.scale; +import sm.vec; +import sm.vvec; #include #include diff --git a/mplot/RectangleVisual.h b/mplot/RectangleVisual.h index 4163b1da..ba20f87b 100644 --- a/mplot/RectangleVisual.h +++ b/mplot/RectangleVisual.h @@ -1,9 +1,9 @@ #pragma once #include -#include +import sm.vec; #include -#include +import sm.mat; #include namespace mplot diff --git a/mplot/RhomboVisual.h b/mplot/RhomboVisual.h index a06b2694..7f945749 100644 --- a/mplot/RhomboVisual.h +++ b/mplot/RhomboVisual.h @@ -1,7 +1,7 @@ #pragma once #include -#include +import sm.vec; #include #include diff --git a/mplot/RingVisual.h b/mplot/RingVisual.h index a6e8ec90..3bc573fb 100644 --- a/mplot/RingVisual.h +++ b/mplot/RingVisual.h @@ -1,7 +1,7 @@ #pragma once #include -#include +import sm.vec; #include namespace mplot diff --git a/mplot/ScatterVisual.h b/mplot/ScatterVisual.h index bf65af49..51f9f55a 100644 --- a/mplot/ScatterVisual.h +++ b/mplot/ScatterVisual.h @@ -9,7 +9,7 @@ #include #include #include -#include +import sm.vec; #include #include #include diff --git a/mplot/SphereVisual.h b/mplot/SphereVisual.h index d8e0e543..658bc4d4 100644 --- a/mplot/SphereVisual.h +++ b/mplot/SphereVisual.h @@ -4,7 +4,7 @@ #pragma once #include -#include +import sm.vec; #include namespace mplot diff --git a/mplot/SphericalProjectionVisual.h b/mplot/SphericalProjectionVisual.h index dd3ffe43..f710ce23 100644 --- a/mplot/SphericalProjectionVisual.h +++ b/mplot/SphericalProjectionVisual.h @@ -3,9 +3,9 @@ #include #include #include -#include -#include -#include +import sm.vec; +import sm.range; +import sm.geometry; #include #include #include diff --git a/mplot/TriFrameVisual.h b/mplot/TriFrameVisual.h index 5baf8e00..699f6c4e 100644 --- a/mplot/TriFrameVisual.h +++ b/mplot/TriFrameVisual.h @@ -5,7 +5,7 @@ #include #include -#include +import sm.vec; #include #include diff --git a/mplot/TriangleVisual.h b/mplot/TriangleVisual.h index d25bef26..f0a6f5e5 100644 --- a/mplot/TriangleVisual.h +++ b/mplot/TriangleVisual.h @@ -1,7 +1,7 @@ #pragma once #include -#include +import sm.vec; #include namespace mplot diff --git a/mplot/TriaxesVisual.h b/mplot/TriaxesVisual.h index dbec4d7e..699d5580 100644 --- a/mplot/TriaxesVisual.h +++ b/mplot/TriaxesVisual.h @@ -6,9 +6,9 @@ #pragma once #include -#include -#include -#include +import sm.scale; +import sm.vec; +import sm.quaternion; #include #include #include // Share tickstyle, axestyle diff --git a/mplot/TxtVisual.h b/mplot/TxtVisual.h index 5cbbdcd7..7a77ce15 100644 --- a/mplot/TxtVisual.h +++ b/mplot/TxtVisual.h @@ -8,7 +8,7 @@ #include #include -#include +import sm.vec; #include #include diff --git a/mplot/VectorVisual.h b/mplot/VectorVisual.h index af405b43..01272d55 100644 --- a/mplot/VectorVisual.h +++ b/mplot/VectorVisual.h @@ -5,7 +5,7 @@ */ #include -#include +import sm.vec; #include #include #include diff --git a/mplot/VerticesVisual.h b/mplot/VerticesVisual.h index 34513f36..28107690 100644 --- a/mplot/VerticesVisual.h +++ b/mplot/VerticesVisual.h @@ -7,9 +7,9 @@ #include #include -#include -#include -#include +import sm.vec; +import sm.vvec; +import sm.mat; #include diff --git a/mplot/VoronoiVisual.h b/mplot/VoronoiVisual.h index 1e990237..8146020d 100644 --- a/mplot/VoronoiVisual.h +++ b/mplot/VoronoiVisual.h @@ -18,11 +18,11 @@ #include #include -#include -#include -#include -#include -#include +import sm.vec; +import sm.range; +import sm.quaternion; +import sm.geometry; +import sm.centroid; #include #include diff --git a/mplot/compoundray/EyeVisual.h b/mplot/compoundray/EyeVisual.h index bcea798a..3f1c5433 100644 --- a/mplot/compoundray/EyeVisual.h +++ b/mplot/compoundray/EyeVisual.h @@ -7,11 +7,11 @@ #include #include #include -#include -#include -#include -#include -#include +import sm.vec; +import sm.mat; +import sm.range; +import sm.geometry; +import sm.centroid; #include #include #include diff --git a/mplot/compoundray/interop.h b/mplot/compoundray/interop.h index c97fc8c4..e8aec8c4 100644 --- a/mplot/compoundray/interop.h +++ b/mplot/compoundray/interop.h @@ -13,8 +13,8 @@ #include // maths and mathplot includes -#include -#include +import sm.vec; +import sm.mat; #include #include diff --git a/mplot/gl/compute_shaderprog.h b/mplot/gl/compute_shaderprog.h index 2f825795..6976a13b 100644 --- a/mplot/gl/compute_shaderprog.h +++ b/mplot/gl/compute_shaderprog.h @@ -5,8 +5,8 @@ #include #include -#include -#include +import sm.vec; +import sm.vvec; #include #include diff --git a/mplot/gl/ssbo_nomx.h b/mplot/gl/ssbo_nomx.h index 24c4c222..aee4cef7 100644 --- a/mplot/gl/ssbo_nomx.h +++ b/mplot/gl/ssbo_nomx.h @@ -10,9 +10,9 @@ */ #include -#include -#include -#include +import sm.vec; +import sm.vvec; +import sm.range; #include namespace mplot::gl diff --git a/mplot/gl/texture.h b/mplot/gl/texture.h index 16e3d5c7..b82b0405 100644 --- a/mplot/gl/texture.h +++ b/mplot/gl/texture.h @@ -11,7 +11,7 @@ #include #include -#include +import sm.vec; #include namespace mplot::gl diff --git a/mplot/graphing.h b/mplot/graphing.h index 5c3acadc..00642e9e 100644 --- a/mplot/graphing.h +++ b/mplot/graphing.h @@ -21,9 +21,9 @@ # include #endif -#include -#include -#include +import sm.range; +import sm.algo; +import sm.vvec; namespace mplot::graphing { diff --git a/mplot/jcvoronoi/jc_voronoi.h b/mplot/jcvoronoi/jc_voronoi.h index ba317437..1f5bc1f6 100644 --- a/mplot/jcvoronoi/jc_voronoi.h +++ b/mplot/jcvoronoi/jc_voronoi.h @@ -21,9 +21,9 @@ #include // uintptr_t etc #include #include -#include -#include -#include +import sm.vec; +import sm.geometry; +import sm.winder; #ifndef JCV_EDGE_INTERSECT_THRESHOLD // Fix for Issue #40 diff --git a/mplot/loadpng.h b/mplot/loadpng.h index 6909f070..833cf5ff 100644 --- a/mplot/loadpng.h +++ b/mplot/loadpng.h @@ -14,8 +14,8 @@ #include #include -#include -#include +import sm.vec; +import sm.vvec; namespace mplot { From c75f9fc9643289bac57c3e6ef584286de9213143 Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 5 Mar 2026 13:19:29 +0000 Subject: [PATCH 008/106] Changes required to compile showcase with moduled maths --- examples/CMakeLists.txt | 4 ++++ examples/showcase.cpp | 2 ++ mplot/graphing.h | 1 + 3 files changed, 7 insertions(+) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7427ee53..d5412821 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -99,6 +99,10 @@ if(ARMADILLO_FOUND) ${PROJECT_SOURCE_DIR}/maths/sm/geometry ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra ${PROJECT_SOURCE_DIR}/maths/sm/grid + ${PROJECT_SOURCE_DIR}/maths/sm/histo + ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex + ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord + ${PROJECT_SOURCE_DIR}/maths/sm/hex ) target_link_libraries(showcase OpenGL::GL glfw Freetype::Freetype) endif(ARMADILLO_FOUND) diff --git a/examples/showcase.cpp b/examples/showcase.cpp index 823cc6d3..28aafa98 100644 --- a/examples/showcase.cpp +++ b/examples/showcase.cpp @@ -371,3 +371,5 @@ int main() return 0; } + + diff --git a/mplot/graphing.h b/mplot/graphing.h index 00642e9e..a595de2f 100644 --- a/mplot/graphing.h +++ b/mplot/graphing.h @@ -21,6 +21,7 @@ # include #endif +#include import sm.range; import sm.algo; import sm.vvec; From 7686f17592cb89b303c33766b6f2b7a3f769beb4 Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 5 Mar 2026 15:06:40 +0000 Subject: [PATCH 009/106] Welcome to circular dependency hell. --- examples/CMakeLists.txt | 30 ++++++++++++++++++++++++++++++ examples/helloworld.cpp | 5 ++--- examples/rod.cpp | 4 ++-- mplot/TextFeatures.h | 9 ++++++--- mplot/TextGeometry.h | 4 ++-- mplot/Visual.h | 15 +++++++++------ mplot/VisualBase.h | 26 +++++++++++++++----------- mplot/VisualCommon.h | 14 +++++++------- mplot/VisualFace.h | 21 +++++++++++++++------ mplot/VisualFaceBase.h | 16 +++++++++++----- mplot/VisualFont.h | 4 ++-- mplot/VisualGlfw.h | 8 +++++--- mplot/VisualModel.h | 8 +++++--- mplot/VisualModelBase.h | 7 +++++-- mplot/VisualOwnable.h | 19 +++++++++---------- mplot/VisualResources.h | 24 +++++++++++++++++++----- mplot/VisualResourcesBase.h | 11 +++++++---- mplot/VisualTextModel.h | 20 ++++++++++++++------ mplot/VisualTextModelBase.h | 37 +++++++++++++++++++++---------------- 19 files changed, 186 insertions(+), 96 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index d5412821..ad990ff3 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -25,12 +25,42 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra ${PROJECT_SOURCE_DIR}/maths/sm/flags ${PROJECT_SOURCE_DIR}/maths/sm/centroid + ${PROJECT_SOURCE_DIR}/mplot/VisualBase.h + ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h + ${PROJECT_SOURCE_DIR}/mplot/Visual.h + ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFaceBase.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h + ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h + ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h + ${PROJECT_SOURCE_DIR}/mplot/VisualResourcesBase.h + ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h + ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h + ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualTextModelBase.h + ${PROJECT_SOURCE_DIR}/mplot/core.ixx PROPERTIES LANGUAGE CXX ) add_executable(helloworld helloworld.cpp) target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES + ${PROJECT_SOURCE_DIR}/mplot/core.ixx + ${PROJECT_SOURCE_DIR}/mplot/VisualBase.h + ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h + ${PROJECT_SOURCE_DIR}/mplot/Visual.h + ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFaceBase.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h + ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h + ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h + ${PROJECT_SOURCE_DIR}/mplot/VisualResourcesBase.h + ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h + ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h + ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualTextModelBase.h ${PROJECT_SOURCE_DIR}/maths/sm/flags ${PROJECT_SOURCE_DIR}/maths/sm/algo ${PROJECT_SOURCE_DIR}/maths/sm/range diff --git a/examples/helloworld.cpp b/examples/helloworld.cpp index dc5e4750..911afb5e 100644 --- a/examples/helloworld.cpp +++ b/examples/helloworld.cpp @@ -1,4 +1,5 @@ -#include +import mplot.core; + int main() { mplot::Visual v(600, 400, "Hello World!"); @@ -6,5 +7,3 @@ int main() v.keepOpen(); return 0; } - - diff --git a/examples/rod.cpp b/examples/rod.cpp index 5189f1ac..5ccdb8d5 100644 --- a/examples/rod.cpp +++ b/examples/rod.cpp @@ -9,9 +9,9 @@ #include #include +#include // import mplot.core; -#include -#include +#include // import mplot.gridvisual; import sm.vec; diff --git a/mplot/TextFeatures.h b/mplot/TextFeatures.h index e8d73664..e25bea57 100644 --- a/mplot/TextFeatures.h +++ b/mplot/TextFeatures.h @@ -1,10 +1,13 @@ -#pragma once +module; #include #include -#include -namespace mplot +export module mplot.core:textfeatures; + +import :visualfont; + +export namespace mplot { // A way to bundle up font size, colour, etc into a single object. Constructors chosen for max convenience. struct TextFeatures diff --git a/mplot/TextGeometry.h b/mplot/TextGeometry.h index 9cc9815a..72be198f 100644 --- a/mplot/TextGeometry.h +++ b/mplot/TextGeometry.h @@ -1,6 +1,6 @@ -#pragma once +export module mplot.core:textgeometry; -namespace mplot +export namespace mplot { /*! * A class containing information about a text string, as it would be displayed on diff --git a/mplot/Visual.h b/mplot/Visual.h index 74c47e73..996e6f25 100644 --- a/mplot/Visual.h +++ b/mplot/Visual.h @@ -15,7 +15,7 @@ * \author Seb James * \date May 2025 */ -#pragma once +module; #ifndef _glfw3_h_ // glfw3 has not yet been externally included # define GLFW_INCLUDE_NONE // Here, we tell GLFW that we will explicitly include GL3/gl3.h and GL/glext.h @@ -25,16 +25,19 @@ #include #include -namespace mplot +export module mplot.core:visual; + +export import :visualglfw; + +export import :visualownable; + +export namespace mplot { // With mplot::Visual, we use a GLFW window which is owned by mplot::Visual. using win_t = GLFWwindow; } -#include -#include - -namespace mplot +export namespace mplot { /*! * Visual 'scene' class diff --git a/mplot/VisualBase.h b/mplot/VisualBase.h index e334162a..60be96c0 100644 --- a/mplot/VisualBase.h +++ b/mplot/VisualBase.h @@ -7,7 +7,7 @@ * \author Seb James * \date March 2025 */ -#pragma once +module; #include #include @@ -18,22 +18,14 @@ #include #include -import sm.range; -import sm.flags; -import sm.quaternion; -import sm.mat; -import sm.vec; - #include #include -#include -#include -#include #include #include #include #include + #include #include #include @@ -45,7 +37,19 @@ import sm.vec; #define LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS 1 #include -namespace mplot +export module mplot.core:visualbase; + +import sm.range; +import sm.flags; +import sm.quaternion; +import sm.mat; +import sm.vec; + +import :textfeatures; +import :textgeometry; +import :visualcommon; + +export namespace mplot { //! Here are our boolean state flags enum class visual_state : uint32_t diff --git a/mplot/VisualCommon.h b/mplot/VisualCommon.h index 49248bb8..14b6a359 100644 --- a/mplot/VisualCommon.h +++ b/mplot/VisualCommon.h @@ -1,26 +1,26 @@ -#pragma once - /* * Common code for GL functionality in mathplot programs. * * Author: Seb James. */ +module; #include #include #include #include #include +#include +#include + +export module mplot.core:visualcommon; import sm.vec; import sm.range; import sm.vvec; import sm.mat; -#include -#include - -namespace mplot +export namespace mplot { // A very simple mesh struct. No textures, materials or owt struct meshgroup @@ -47,7 +47,7 @@ namespace mplot }; } -namespace mplot::visgl +export namespace mplot::visgl { // A container struct for the shader program identifiers used in a mplot::Visual. Separate // from mplot::Visual so that it can be used in mplot::VisualModel as well, which does not diff --git a/mplot/VisualFace.h b/mplot/VisualFace.h index b0ce482e..9e9d89d7 100644 --- a/mplot/VisualFace.h +++ b/mplot/VisualFace.h @@ -10,18 +10,27 @@ * \author Seb James * \date November 2020 */ - -#pragma once - -#include +module; #if defined __gl3_h_ || defined __gl_h_ // GL headers have been externally included #else -# error "GL headers should have been included already" +// Include GLAD header +# define GLAD_GL_IMPLEMENTATION +# include #endif -namespace mplot::visgl +// FreeType for text rendering +#include +#include FT_FREETYPE_H + +#include + +export module mplot.core:visualface; + +import :visualfacebase; + +export namespace mplot::visgl { struct VisualFace : public mplot::visgl::VisualFaceBase { diff --git a/mplot/VisualFaceBase.h b/mplot/VisualFaceBase.h index b1f11841..a9f79642 100644 --- a/mplot/VisualFaceBase.h +++ b/mplot/VisualFaceBase.h @@ -9,8 +9,7 @@ * \author Seb James * \date November 2020 */ - -#pragma once +module; #include #include @@ -18,9 +17,6 @@ #include #include -#include // for visgl::CharInfo -#include -#include // FreeType for text rendering #include @@ -161,6 +157,16 @@ extern const char __start_dvsansbi_ttf[]; extern const char __stop_dvsansbi_ttf[]; #endif +/* + * Module starts here + */ + +export module mplot.core:visualfacebase; + +import :visualcommon; +import :visualfont; +import :textfeatures; + namespace mplot::visgl { struct VisualFaceBase diff --git a/mplot/VisualFont.h b/mplot/VisualFont.h index 9d620373..6ef402bc 100644 --- a/mplot/VisualFont.h +++ b/mplot/VisualFont.h @@ -1,10 +1,10 @@ -#pragma once +export module mplot.core:visualfont; /* * This is just an enumerated class that defines the fonts we pack into a mplot binary */ -namespace mplot +export namespace mplot { //! The fonts supported (i.e. compiled in) to mplot::Visual enum class VisualFont diff --git a/mplot/VisualGlfw.h b/mplot/VisualGlfw.h index c8d306f8..2933c7b4 100644 --- a/mplot/VisualGlfw.h +++ b/mplot/VisualGlfw.h @@ -6,8 +6,7 @@ * \author Seb James * \date March 2025 */ - -#pragma once +module; #ifndef _glfw3_h_ # define GLFW_INCLUDE_NONE @@ -16,8 +15,11 @@ #include #include +#include + +export module mplot.core:visualglfw; -namespace mplot +export namespace mplot { //! Singleton resource class for mplot::Visual scenes. template diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index e2f8d55a..19db3c1a 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -14,7 +14,9 @@ #if defined __gl3_h_ || defined __gl_h_ // GL headers have been externally included #else -# error "GL headers should have been included already" +// Include GLAD header +# define GLAD_GL_IMPLEMENTATION +# include #endif #include @@ -22,8 +24,8 @@ #include #include -#include -#include + +import mplot.core; namespace mplot { diff --git a/mplot/VisualModelBase.h b/mplot/VisualModelBase.h index 2f971470..ae63a834 100644 --- a/mplot/VisualModelBase.h +++ b/mplot/VisualModelBase.h @@ -15,7 +15,9 @@ #if defined __gl3_h_ || defined __gl_h_ // GL headers have been externally included #else -# error "GL headers should have been included already" +// Include GLAD header +# define GLAD_GL_IMPLEMENTATION +# include #endif #include @@ -47,7 +49,8 @@ import sm.range; import sm.algo; import sm.flags; -#include +import mplot.core; + #include #include #include diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index 446310c2..71f2126b 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -14,7 +14,7 @@ * \author Seb James * \date March 2025 */ -#pragma once +module; #if defined __gl3_h_ || defined __gl_h_ // could get a fuller list from glfw.h // GL headers appear to have been externally included. @@ -24,18 +24,17 @@ # include #endif // GL headers -// By including this header, you take out a contract that you ARE using multicontext (MX) GLAD -// headers. This must appear BEFORE the rest of the mplot headers. No longer used as we ALWAYS use -// MX and never NoMX now. -// namespace mplot::gl { static constexpr int multicontext = 1; } - -#include -#include -#include #include #include +#include + +export module mplot.core:visualownable; + +import :visualresources; +import :visualtextmodel; +import :visualbase; -namespace mplot +export namespace mplot { /*! * VisualOwnable - adds multi-context-safe GL calls to the 'scene' base class, VisualBase diff --git a/mplot/VisualResources.h b/mplot/VisualResources.h index 94e414e9..e8a2dd67 100644 --- a/mplot/VisualResources.h +++ b/mplot/VisualResources.h @@ -7,8 +7,7 @@ * \author Seb James * \date November 2020 */ - -#pragma once +module; #include #include @@ -17,14 +16,29 @@ #include #include -#include -#include +#if defined __gl3_h_ || defined __gl_h_ +// GL headers have been externally included +#else +// Include GLAD header +# define GLAD_GL_IMPLEMENTATION +# include +#endif + +#include #include #include +// FreeType for text rendering +#include +#include FT_FREETYPE_H + +export module mplot.core:visualresources; +import :visualface; +import :visualresourcesbase; + import sm.vec; -namespace mplot +export namespace mplot { // Pointers to mplot::VisualBase are used to index font faces template diff --git a/mplot/VisualResourcesBase.h b/mplot/VisualResourcesBase.h index aec053ab..697964e0 100644 --- a/mplot/VisualResourcesBase.h +++ b/mplot/VisualResourcesBase.h @@ -7,17 +7,20 @@ * \author Seb James * \date November 2020 */ - -#pragma once +module; #include +#include #include -#include // FreeType for text rendering #include #include FT_FREETYPE_H -namespace mplot +export module mplot.core:visualresourcesbase; + +import :visualfont; + +export namespace mplot { // Pointers to mplot::VisualBase are used to index font faces template diff --git a/mplot/VisualTextModel.h b/mplot/VisualTextModel.h index ef961635..fa450c50 100644 --- a/mplot/VisualTextModel.h +++ b/mplot/VisualTextModel.h @@ -14,20 +14,28 @@ * \author Seb James * \date Oct 2020 - Mar 2026 */ +module; -#pragma once - -#include +#include +#include #if defined __gl3_h_ || defined __gl_h_ // GL headers have been externally included #else -# error "GL headers should have been included already" +// Include GLAD header +# define GLAD_GL_IMPLEMENTATION +# include #endif +#include #include -#include -#include +#include + +export module mplot.core:visualtextmodel; + +import :visualtextmodelbase; +import :visualface; +import :visualresources; import sm.vec; diff --git a/mplot/VisualTextModelBase.h b/mplot/VisualTextModelBase.h index 59019d62..9abe9541 100644 --- a/mplot/VisualTextModelBase.h +++ b/mplot/VisualTextModelBase.h @@ -6,29 +6,34 @@ * \author Seb James * \date March 2025 */ +module; -#pragma once - +#include +#include #include #include #include #include #include +#include -#include +#include -#include +#include #include -#include -#include #include -#include +export module mplot.core:visualtextmodelbase; + +import :visualcommon; +import :textgeometry; +import :textfeatures; + import sm.quaternion; import sm.mat; import sm.vec; -namespace mplot +export namespace mplot { //! Forward declaration of a VisualBase class template class VisualBase; @@ -183,7 +188,7 @@ namespace mplot // Two triangles per quad // qi * 4 + 1, 2 3 or 4 - GLuint ib = (GLuint)qi*4; + uint32_t ib = (uint32_t)qi*4; this->indices.push_back (ib++); // 0 this->indices.push_back (ib++); // 1 this->indices.push_back (ib); // 2 @@ -214,9 +219,9 @@ namespace mplot */ std::function*)> get_shaderprogs; //! Get the graphics shader prog id - std::function*)> get_gprog; + std::function*)> get_gprog; //! Get the text shader prog id - std::function*)> get_tprog; + std::function*)> get_tprog; //! Set OpenGL context. Should call parentVis->setContext(). std::function*)> setContext; @@ -272,13 +277,13 @@ namespace mplot //! Position within vertex buffer object (if I use an array of VBO) enum VBOPos { posnVBO, normVBO, colVBO, idxVBO, textureVBO, numVBO }; //! The OpenGL Vertex Array Object - GLuint vao = 0; + uint32_t vao = 0; //! Single vbo to use as in example - GLuint vbo = 0; + uint32_t vbo = 0; //! Vertex Buffer Objects stored in an array - std::unique_ptr vbos; + std::unique_ptr vbos; //! CPU-side data for indices - std::vector indices = {}; + std::vector indices = {}; //! CPU-side data for quad vertex positions std::vector vertexPositions = {}; //! CPU-side data for quad vertex normals @@ -293,7 +298,7 @@ namespace mplot bool hide = false; //! Set up a vertex buffer object - bind, buffer and set vertex array object attribute - virtual void setupVBO (GLuint& buf, std::vector& dat, unsigned int bufferAttribPosition) = 0; + virtual void setupVBO (uint32_t& buf, std::vector& dat, unsigned int bufferAttribPosition) = 0; //! Push three floats onto the vector of floats \a vp void vertex_push (const float& x, const float& y, const float& z, std::vector& vp) From c892bd77ceb9bd0a9e03e47381f4986aad8388ac Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 5 Mar 2026 15:36:01 +0000 Subject: [PATCH 010/106] The circular dependency problem is that VisualBase needs to know about VisualModel and VisualModel about VisualBase --- mplot/Visual.h | 18 ++++++++---------- mplot/VisualBase.h | 32 ++++++++++++++++++++++++++++---- mplot/VisualModel.h | 2 +- mplot/VisualModelBase.h | 2 +- mplot/core.ixx | 2 ++ mplot/gl/loadshaders_mx.h | 23 ++++++++++++----------- mplot/gl/shaders.h | 14 +++++++------- mplot/win_t.h | 14 ++++++++++++++ 8 files changed, 73 insertions(+), 34 deletions(-) create mode 100644 mplot/core.ixx create mode 100644 mplot/win_t.h diff --git a/mplot/Visual.h b/mplot/Visual.h index 996e6f25..be6c9cc4 100644 --- a/mplot/Visual.h +++ b/mplot/Visual.h @@ -17,25 +17,23 @@ */ module; -#ifndef _glfw3_h_ // glfw3 has not yet been externally included -# define GLFW_INCLUDE_NONE // Here, we tell GLFW that we will explicitly include GL3/gl3.h and GL/glext.h -# include -#endif // _glfw3_h_ - #include #include export module mplot.core:visual; +export import :win_t; + export import :visualglfw; export import :visualownable; -export namespace mplot -{ - // With mplot::Visual, we use a GLFW window which is owned by mplot::Visual. - using win_t = GLFWwindow; -} +// Has to be a module partition? +//namespace mplot +//{ +// // With mplot::Visual, we use a GLFW window which is owned by mplot::Visual. +// using win_t = GLFWwindow; +//} export namespace mplot { diff --git a/mplot/VisualBase.h b/mplot/VisualBase.h index 60be96c0..c350d796 100644 --- a/mplot/VisualBase.h +++ b/mplot/VisualBase.h @@ -19,15 +19,27 @@ module; #include #include -#include + +#if defined __gl3_h_ || defined __gl_h_ +// GL headers have been externally included +#else +// Include GLAD header +# define GLAD_GL_IMPLEMENTATION +# include +#endif + +// THIS include is the issue +// #include + #include #include #include #include -#include -#include +// And these +//#include +//#include #include #include @@ -45,6 +57,7 @@ import sm.quaternion; import sm.mat; import sm.vec; +import :win_t; import :textfeatures; import :textgeometry; import :visualcommon; @@ -155,6 +168,11 @@ export namespace mplot static constexpr double retinaScale = 1; // Qt has devicePixelRatio() to get retinaScale. #endif + // Forward declare VisualModels + template class VisualModel; + template class CoordArrows; + template class RodVisual; + /*! * VisualBase, the mplot::Visual 'scene' base class * @@ -385,6 +403,7 @@ export namespace mplot //! Compute position and rotation of coordinate arrows in the bottom left of the screen void positionCoordArrows() { +#if 0 // Find out the location of the bottom left of the screen and make the coord // arrows stay put there. @@ -401,32 +420,37 @@ export namespace mplot v0.set_from ((this->invproj * p0)); // Translate the scene for the CoordArrows such that they sit in a single position on // the screen - this->coordArrows->setSceneTranslation (v0); + this->coordArrows->setSceneTranslation (v0); // argh. method. // Apply rotation to the coordArrows model sm::quaternion svrq = this->sceneview.rotation(); svrq.renormalize(); this->coordArrows->setViewRotation (svrq); +#endif } // Update the coordinate axes labels void updateCoordLabels (const std::string& x_lbl, const std::string& y_lbl, const std::string& z_lbl) { +#if 0 this->coordArrows->clear(); this->coordArrows->x_label = x_lbl; this->coordArrows->y_label = y_lbl; this->coordArrows->z_label = z_lbl; this->coordArrows->initAxisLabels(); this->coordArrows->reinit(); +#endif } // Update the lengths of the CoordArrows that (usually) appear in the corner of the screen void updateCoordLengths (const sm::vec& _lengths, const float _thickness = 1.0f) { +#if 0 this->coordArrows->lengths = _lengths; this->coordArrows->thickness = _thickness; this->coordArrows->clear(); this->coordArrows->initAxisLabels(); this->coordArrows->reinit(); +#endif } // state defaults. All state is false by default diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index 19db3c1a..21d7c22f 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -25,7 +25,7 @@ #include -import mplot.core; +import mplot.core; // To know about VisualBase and VisualOwnable static methods namespace mplot { diff --git a/mplot/VisualModelBase.h b/mplot/VisualModelBase.h index ae63a834..01c6ed6d 100644 --- a/mplot/VisualModelBase.h +++ b/mplot/VisualModelBase.h @@ -49,7 +49,7 @@ import sm.range; import sm.algo; import sm.flags; -import mplot.core; +//import mplot.core;// Can I avoid use of this in VisualModelBase? #include #include diff --git a/mplot/core.ixx b/mplot/core.ixx new file mode 100644 index 00000000..fb9867ea --- /dev/null +++ b/mplot/core.ixx @@ -0,0 +1,2 @@ +export module mplot.core; +export import :visual; diff --git a/mplot/gl/loadshaders_mx.h b/mplot/gl/loadshaders_mx.h index a2ec95e7..cd1173af 100644 --- a/mplot/gl/loadshaders_mx.h +++ b/mplot/gl/loadshaders_mx.h @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -15,14 +16,14 @@ namespace mplot::gl { //! Shader loading code. - GLuint LoadShadersMX (const std::vector& shader_info, GladGLContext* glfn) + uint32_t LoadShadersMX (const std::vector& shader_info, GladGLContext* glfn) { if (shader_info.empty()) { return 0; } - GLuint program = glfn->CreateProgram(); + uint32_t program = glfn->CreateProgram(); #ifdef GL_SHADER_COMPILER - GLboolean shaderCompilerPresent = GL_FALSE; + uint8_t shaderCompilerPresent = GL_FALSE; glfn->GetBooleanv (GL_SHADER_COMPILER, &shaderCompilerPresent); if (shaderCompilerPresent == GL_FALSE) { std::cerr << "Shader compiler NOT present!\n"; @@ -33,11 +34,11 @@ namespace mplot::gl } #endif for (auto entry : shader_info) { - GLuint shader = glfn->CreateShader (entry.type); + uint32_t shader = glfn->CreateShader (entry.type); entry.shader = shader; // Test entry.filename. If this GLSL file can be read, then do so, otherwise, // compile the default version specified in the ShaderInfo - std::unique_ptr source; + std::unique_ptr source; if constexpr (debug_shaders == true) { std::cout << "Check file exists for " << entry.filename << std::endl; } @@ -64,11 +65,11 @@ namespace mplot::gl std::cout << source.get() << "-----\n"; } } - GLint slen = (GLint)std::strlen (source.get()); - const GLchar* sptr = source.get(); + int32_t slen = (int32_t)std::strlen (source.get()); + const char* sptr = source.get(); glfn->ShaderSource (shader, 1, &sptr, &slen); glfn->CompileShader (shader); - GLint shaderCompileSuccess = GL_FALSE; + int32_t shaderCompileSuccess = GL_FALSE; char infoLog[512]; glfn->GetShaderiv(shader, GL_COMPILE_STATUS, &shaderCompileSuccess); if (!shaderCompileSuccess) { @@ -99,14 +100,14 @@ namespace mplot::gl glfn->DeleteShader (shader); // Note it's correct to glDeleteShader after attaching it to program } - GLint linked = 0; + int32_t linked = 0; glfn->LinkProgram (program); glfn->GetProgramiv (program, GL_LINK_STATUS, &linked); if (!linked) { - GLsizei len = 0; + int32_t len = 0; glfn->GetProgramiv (program, GL_INFO_LOG_LENGTH, &len); { - std::unique_ptr log = std::make_unique(len+1); + std::unique_ptr log = std::make_unique(len+1); glfn->GetProgramInfoLog (program, len, &len, log.get()); std::cerr << "Shader linking failed: " << log.get() << std::endl << "Exiting.\n"; } diff --git a/mplot/gl/shaders.h b/mplot/gl/shaders.h index e98258e2..88fa0a17 100644 --- a/mplot/gl/shaders.h +++ b/mplot/gl/shaders.h @@ -39,21 +39,21 @@ namespace mplot::gl unsigned int type; // rather than GLenum std::string filename; std::string compiledIn; - GLuint shader; + uint32_t shader; }; // To enable debugging, set true. const bool debug_shaders = false; //! Read a shader from a file. - std::unique_ptr ReadShader (const std::string& filename) + std::unique_ptr ReadShader (const std::string& filename) { if (!std::filesystem::is_regular_file (filename)) { // restrict to regular files std::cerr << "'" << filename << "' is not a regular file\n"; return nullptr; } size_t len = std::filesystem::file_size (filename); - std::unique_ptr source = std::make_unique(len + 1); + std::unique_ptr source = std::make_unique(len + 1); std::ifstream fin (filename.c_str(), std::ios::in); if (!fin.is_open()) { std::cerr << "Unable to open file '" << filename << "'\n"; @@ -67,18 +67,18 @@ namespace mplot::gl /*! * Read a default shader, stored as a const char*. ReadDefaultShader reads a * file: allocates some memory, copies the text into the new memory and then - * returns a GLchar* pointer to the memory. + * returns a char* pointer to the memory. */ - std::unique_ptr ReadDefaultShader (const std::string& shadercontent) + std::unique_ptr ReadDefaultShader (const std::string& shadercontent) { std::size_t len = shadercontent.size(); - std::unique_ptr source = std::make_unique(len + 1); + std::unique_ptr source = std::make_unique(len + 1); std::memcpy (static_cast(source.get()), static_cast(shadercontent.c_str()), len); source[len] = 0; return source; } - std::string shader_type_str (GLuint shader_type) + std::string shader_type_str (uint32_t shader_type) { std::string type("unknown"); if (shader_type == GL_VERTEX_SHADER) { diff --git a/mplot/win_t.h b/mplot/win_t.h new file mode 100644 index 00000000..7c26997d --- /dev/null +++ b/mplot/win_t.h @@ -0,0 +1,14 @@ +module; + +#ifndef _glfw3_h_ // glfw3 has not yet been externally included +# define GLFW_INCLUDE_NONE // Here, we tell GLFW that we will explicitly include GL3/gl3.h and GL/glext.h +# include +#endif // _glfw3_h_ + +export module mplot.core:win_t; + +export namespace mplot +{ + // With mplot::Visual, we use a GLFW window which is owned by mplot::Visual. + using win_t = GLFWwindow; +} From d4b27ca7b34292a9738e045c9d6064c2669ad8c3 Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 5 Mar 2026 16:54:51 +0000 Subject: [PATCH 011/106] Trying to write VisualModels out of mplot::Visual --- examples/CMakeLists.txt | 4 + examples/helloworld.cpp | 1 + mplot/CoordArrows.h | 485 ++++++++++++++++++++++++++++++++++++++-- mplot/Visual.h | 7 + mplot/VisualBase.h | 34 +-- mplot/VisualCommon.h | 12 + mplot/VisualModelBase.h | 14 +- mplot/VisualOwnable.h | 31 ++- mplot/VisualTextModel.h | 2 +- 9 files changed, 517 insertions(+), 73 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ad990ff3..38b35a85 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -39,6 +39,8 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h ${PROJECT_SOURCE_DIR}/mplot/VisualTextModelBase.h + ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h + ${PROJECT_SOURCE_DIR}/mplot/win_t.h ${PROJECT_SOURCE_DIR}/mplot/core.ixx PROPERTIES LANGUAGE CXX ) @@ -47,6 +49,8 @@ add_executable(helloworld helloworld.cpp) target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${PROJECT_SOURCE_DIR}/mplot/core.ixx + ${PROJECT_SOURCE_DIR}/mplot/win_t.h + ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h ${PROJECT_SOURCE_DIR}/mplot/VisualBase.h ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h ${PROJECT_SOURCE_DIR}/mplot/Visual.h diff --git a/examples/helloworld.cpp b/examples/helloworld.cpp index 911afb5e..d3ed7995 100644 --- a/examples/helloworld.cpp +++ b/examples/helloworld.cpp @@ -1,3 +1,4 @@ +#include import mplot.core; int main() diff --git a/mplot/CoordArrows.h b/mplot/CoordArrows.h index c0137a30..978393bb 100644 --- a/mplot/CoordArrows.h +++ b/mplot/CoordArrows.h @@ -1,34 +1,59 @@ /*! * \file * - * Defines a coordinate arrow class + * Defines a non-VisualModel coordinate arrow class for internal use in the scene (bottom left corner). * * \author Seb James * \date 2019 */ -#pragma once +module; + +#if defined __gl3_h_ || defined __gl_h_ // could get a fuller list from glfw.h +// GL headers appear to have been externally included. +#else +// Include GLAD header +# define GLAD_GL_IMPLEMENTATION +# include +#endif // GL headers #include -import sm.vec; +#include +#include +#include + +#include + #include -#include +#include #include -namespace mplot +export module mplot.core:coordarrows; + +import :visualtextmodel; +import sm.vec; +import sm.mat; +import sm.flags; + +export namespace mplot { + // State/options flags + enum class ca_bools : uint32_t { postVertexInitRequired, hide }; + + //! Forward declaration of a Visual class + //template class VisualBase; + //! This class creates the vertices for a set of coordinate arrows to be rendered //! in a 3-D scene. template - class CoordArrows : public VisualModel + class CoordArrows { public: - CoordArrows() : mplot::VisualModel() {} - CoordArrows (const sm::vec& offset) : mplot::VisualModel(offset) {} + CoordArrows() {} + CoordArrows (const sm::vec& offset) { this->viewmatrix.translate (offset); } //! Must make the boilerplate bindmodel call before calling init() (for text handling) void init (const sm::vec _lengths, const float _thickness, const float _em) { - this->compute_bb (false); this->lengths = _lengths; this->thickness = _thickness; this->em = _em; @@ -37,12 +62,21 @@ namespace mplot //! You can call this AS well as the first init overload to set the axis vectors void init (const sm::vec _x, const sm::vec _y, const sm::vec _z) { - this->compute_bb (false); this->x_axis = _x; this->y_axis = _y; this->z_axis = _z; } + // State/options flags + constexpr sm::flags flags_defaults() + { + sm::flags _flags; + _flags.reset(); // all false + return _flags; + } + sm::flags flags = flags_defaults(); + + //! Make sure coord arrow colours are ok on the given background colour. Call this *after* finalize. void setColourForBackground (const std::array& bgcolour) { @@ -50,25 +84,28 @@ namespace mplot std::array cscol = { 1.0f - bgcolour[0], 1.0f - bgcolour[1], 1.0f - bgcolour[2] }; if (cscol != this->centresphere_col) { this->centresphere_col = cscol; - this->reinit(); // sets context, does not release it - + this->reinit(); // Give the text labels a suitable, visible colour - if (this->setContext != nullptr) { this->setContext (this->parentVis); } + // Don't worry about context, assume its ok. auto ti = this->texts.begin(); while (ti != this->texts.end()) { (*ti)->setVisibleOn (bgcolour); ti++; } - if (this->releaseContext != nullptr) { this->releaseContext (this->parentVis); } } } + std::unique_ptr> makeVisualTextModel(const mplot::TextFeatures& tfeatures) + { + auto tmup = std::make_unique> (tfeatures); + //this->bindmodel (tmup); + return tmup; + } + void initAxisLabels() { if (this->em > 0.0f) { - if (this->setContext != nullptr) { this->setContext (this->parentVis); } // For VisualTextModel - mplot::TextFeatures tfca(this->em, 48, false, mplot::colour::black, mplot::VisualFont::DVSansItalic); // These texts are black by default @@ -89,8 +126,6 @@ namespace mplot auto vtm3 = this->makeVisualTextModel (tfca); vtm3->setupText (this->z_label, toffset); this->texts.push_back (std::move(vtm3)); - - if (this->releaseContext != nullptr) { this->releaseContext (this->parentVis); } } } @@ -166,6 +201,420 @@ namespace mplot std::string x_label = "X"; std::string y_label = "Y"; std::string z_label = "Z"; + + protected: + + // The mplot::VisualBase in which this model exists. + //mplot::VisualBase* parentVis = nullptr; + + //! The current indices index + uint32_t idx = 0u; + + //! The model-specific view matrix. Used to transform the pose of the model in the scene. + sm::mat viewmatrix = {}; + + /*! + * The scene view matrix. Each VisualModel has a copy of the scenematrix. It's set in + * Visual::render. Different VisualModels may have different scenematrices (for example, the + * CoordArrows has a different scenematrix from other VisualModels, and models marked + * 'twodimensional' also have a different scenematrix). + */ + sm::mat scenematrix = {}; + + //! Contains the positions within the vbo array of the different vertex buffer objects + enum VBOPos { posnVBO, normVBO, colVBO, idxVBO, numVBO }; + + /* + * Compute positions and colours of vertices for the hexes and store in these: + */ + + //! The OpenGL Vertex Array Object + uint32_t vao = 0; + + //! Vertex Buffer Objects stored in an array + std::unique_ptr vbos; + + //! CPU-side data for indices + std::vector indices = {}; + //! CPU-side data for vertex positions + std::vector vertexPositions = {}; + //! CPU-side data for vertex normals + std::vector vertexNormals = {}; + //! CPU-side data for vertex colours + std::vector vertexColors = {}; + + GladGLContext* glfn = nullptr; + + //! Common code to call after the vertices have been set up. GL has to have been initialised. + void postVertexInit() + { + GladGLContext* _glfn = this->glfn;// this->get_glfn (this->parentVis); + + // Do gl memory allocation of vertex array once only + if (this->vbos == nullptr) { + // Create vertex array object + _glfn->GenVertexArrays (1, &this->vao); // Safe for OpenGL 4.4- + } + _glfn->BindVertexArray (this->vao); + + // Create the vertex buffer objects (once only) + if (this->vbos == nullptr) { + this->vbos = std::make_unique(this->numVBO); + _glfn->GenBuffers (this->numVBO, this->vbos.get()); // OpenGL 4.4- safe + } + + // Set up the indices buffer - bind and buffer the data in this->indices + _glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos[this->idxVBO]); + + std::size_t sz = this->indices.size() * sizeof(uint32_t); + _glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices.data(), GL_STATIC_DRAW); + + // Binds data from the "C++ world" to the OpenGL shader world for + // "position", "normalin" and "color" + // (bind, buffer and set vertex array object attribute) + this->setupVBO (this->vbos[this->posnVBO], this->vertexPositions, visgl::posnLoc); + this->setupVBO (this->vbos[this->normVBO], this->vertexNormals, visgl::normLoc); + this->setupVBO (this->vbos[this->colVBO], this->vertexColors, visgl::colLoc); + + // Unbind only the vertex array (not the buffers, that causes GL_INVALID_ENUM errors) + _glfn->BindVertexArray(0); // carefully unbind and rebind + mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + + this->flags.set (ca_bools::postVertexInitRequired, false); // Maybe just a bool here + } + + //! Re-create the model - called after updating data + void reinit() + { + // Fixme: Better not to clear, then repeatedly pushback here: + this->vertexPositions.clear(); + this->vertexNormals.clear(); + this->vertexColors.clear(); + this->indices.clear(); + + // NB: Do NOT call clearTexts() here! We're only updating the model itself. + this->idx = 0u; + this->initializeVertices(); + this->reinit_buffers(); + } + + /*! + * Re-initialize the buffers. Client code might have appended to + * vertexPositions/Colors/Normals and indices before calling this method. + */ + void reinit_buffers() + { + GladGLContext* _glfn = this->glfn; // this->get_glfn(this->parentVis); + + // Note that we do not worry about setting context here, we assume the parent Visual has the context + + if (this->flags.test (ca_bools::postVertexInitRequired) == true) { this->postVertexInit(); } + + // Now re-set up the VBOs + _glfn->BindVertexArray (this->vao); // carefully unbind and rebind + _glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos[this->idxVBO]); // carefully unbind and rebind + + std::size_t sz = this->indices.size() * sizeof(uint32_t); + _glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices.data(), GL_STATIC_DRAW); + this->setupVBO (this->vbos[this->posnVBO], this->vertexPositions, visgl::posnLoc); + this->setupVBO (this->vbos[this->normVBO], this->vertexNormals, visgl::normLoc); + this->setupVBO (this->vbos[this->colVBO], this->vertexColors, visgl::colLoc); + + _glfn->BindVertexArray(0); // carefully unbind and rebind + mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); // carefully unbind and rebind + } + + //! A vector of pointers to text models that should be rendered. + std::vector>> texts; + + //! Set up a vertex buffer object - bind, buffer and set vertex array object attribute + void setupVBO (uint32_t& buf, std::vector& dat, unsigned int bufferAttribPosition) + { + std::size_t sz = dat.size() * sizeof(float); + + GladGLContext* _glfn = this->glfn; // this->get_glfn(this->parentVis); + _glfn->BindBuffer (GL_ARRAY_BUFFER, buf); + mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + _glfn->BufferData (GL_ARRAY_BUFFER, sz, dat.data(), GL_STATIC_DRAW); + mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + _glfn->VertexAttribPointer (bufferAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0)); + mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + _glfn->EnableVertexAttribArray (bufferAttribPosition); + mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + } + + //! Push three floats onto the vector of floats \a vp + void vertex_push (const float& x, const float& y, const float& z, std::vector& vp) + { + vp.emplace_back (x); + vp.emplace_back (y); + vp.emplace_back (z); + } + + /*! + * Sphere, 1 colour version. + * + * \param so The sphere offset. Where to place this sphere... + * \param sc The sphere colour. + * \param r Radius of the sphere + * \param rings Number of rings used to render the sphere + * \param segments Number of segments used to render the sphere + */ + void computeSphere (sm::vec so, std::array sc, + float r = 1.0f, int rings = 10, int segments = 12) + { + float rings0 = -sm::mathconst::pi_over_2; + float _z0 = std::sin(rings0); + float z0 = r * _z0; + float r0 = std::cos(rings0); + float rings1 = sm::mathconst::pi * (-0.5f + 1.0f / rings); + float _z1 = std::sin(rings1); + float z1 = r * _z1; + float r1 = std::cos(rings1); + + this->vertex_push (so[0]+0.0f, so[1]+0.0f, so[2]+z0, this->vertexPositions); + this->vertex_push (0.0f, 0.0f, -1.0f, this->vertexNormals); + this->vertex_push (sc, this->vertexColors); + + uint32_t capMiddle = this->idx++; + uint32_t ringStartIdx = this->idx; + uint32_t lastRingStartIdx = this->idx; + + bool firstseg = true; + for (int j = 0; j < segments; j++) { + float segment = sm::mathconst::two_pi * static_cast(j) / segments; + float x = std::cos(segment); + float y = std::sin(segment); + + float _x1 = x*r1; + float x1 = _x1*r; + float _y1 = y*r1; + float y1 = _y1*r; + + this->vertex_push (so[0]+x1, so[1]+y1, so[2]+z1, this->vertexPositions); + this->vertex_push (_x1, _y1, _z1, this->vertexNormals); + this->vertex_push (sc, this->vertexColors); + + if (!firstseg) { + this->indices.push_back (capMiddle); + this->indices.push_back (this->idx-1); + this->indices.push_back (this->idx++); + } else { + this->idx++; + firstseg = false; + } + } + this->indices.push_back (capMiddle); + this->indices.push_back (this->idx-1); + this->indices.push_back (capMiddle+1); + + for (int i = 2; i < rings; i++) { + + rings0 = sm::mathconst::pi * (-0.5f + static_cast(i) / rings); + _z0 = std::sin(rings0); + z0 = r * _z0; + r0 = std::cos(rings0); + + for (int j = 0; j < segments; j++) { + + float segment = sm::mathconst::two_pi * static_cast(j) / segments; + float x = std::cos(segment); + float y = std::sin(segment); + + float _x0 = x*r0; + float x0 = _x0*r; + float _y0 = y*r0; + float y0 = _y0*r; + + this->vertex_push (so[0]+x0, so[1]+y0, so[2]+z0, this->vertexPositions); + this->vertex_push (_x0, _y0, _z0, this->vertexNormals); + this->vertex_push (sc, this->vertexColors); + + if (j == segments - 1) { + this->indices.push_back (ringStartIdx++); + this->indices.push_back (this->idx); + this->indices.push_back (lastRingStartIdx); + this->indices.push_back (lastRingStartIdx); + this->indices.push_back (this->idx++); + this->indices.push_back (lastRingStartIdx+segments); + } else { + this->indices.push_back (ringStartIdx++); + this->indices.push_back (this->idx); + this->indices.push_back (ringStartIdx); + this->indices.push_back (ringStartIdx); + this->indices.push_back (this->idx++); + this->indices.push_back (this->idx); + } + } + lastRingStartIdx += segments; + } + + rings0 = sm::mathconst::pi_over_2; + _z0 = std::sin(rings0); + z0 = r * _z0; + r0 = std::cos(rings0); + + this->vertex_push (so[0]+0.0f, so[1]+0.0f, so[2]+z0, this->vertexPositions); + this->vertex_push (0.0f, 0.0f, 1.0f, this->vertexNormals); + this->vertex_push (sc, this->vertexColors); + capMiddle = this->idx++; + firstseg = true; + + ringStartIdx = lastRingStartIdx; + for (int j = 0; j < segments; j++) { + if (j != segments - 1) { + this->indices.push_back (capMiddle); + this->indices.push_back (ringStartIdx++); + this->indices.push_back (ringStartIdx); + } else { + this->indices.push_back (capMiddle); + this->indices.push_back (ringStartIdx); + this->indices.push_back (lastRingStartIdx); + } + } + } // end of sphere calculation + + /*! + * Create a tube from \a start to \a end, with radius \a r and a colour which + * transitions from the colour \a colStart to \a colEnd. + * + * \param idx The index into the 'vertex array' + * \param start The start of the tube + * \param end The end of the tube + * \param colStart The tube starting colour + * \param colEnd The tube's ending colour + * \param r Radius of the tube + * \param segments Number of segments used to render the tube + */ + void computeTube (sm::vec start, sm::vec end, + std::array colStart, std::array colEnd, + float r = 1.0f, int segments = 12) + { + this->computeFlaredTube (start, end, colStart, colEnd, r, r, segments); + } + + void computeFlaredTube (sm::vec start, sm::vec end, + std::array colStart, std::array colEnd, + float r = 1.0f, int segments = 12, float flare = 0.0f) + { + sm::vec v = end - start; + float l = v.length(); + float r_add = l * std::tan (std::abs(flare)) * (flare > 0.0f ? 1.0f : -1.0f); + float r_end = r + r_add; + this->computeFlaredTube (start, end, colStart, colEnd, r, r_end, segments); + } + + void computeFlaredTube (sm::vec start, sm::vec end, + std::array colStart, std::array colEnd, + float r = 1.0f, float r_end = 1.0f, int segments = 12) + { + sm::vec vstart = start; + sm::vec vend = end; + sm::vec v = vend - vstart; + v.renormalize(); + + sm::vec rand_vec; + rand_vec.randomize(); + sm::vec inplane = rand_vec.cross(v); + inplane.renormalize(); + + sm::vec v_x_inplane = v.cross(inplane); + + this->vertex_push (vstart, this->vertexPositions); + this->vertex_push (-v, this->vertexNormals); + this->vertex_push (colStart, this->vertexColors); + + for (int j = 0; j < segments; j++) { + float t = j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = inplane * std::sin(t) * r + v_x_inplane * std::cos(t) * r; + this->vertex_push (vstart+c, this->vertexPositions); + this->vertex_push (-v, this->vertexNormals); + this->vertex_push (colStart, this->vertexColors); + } + + for (int j = 0; j < segments; j++) { + float t = j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = inplane * std::sin(t) * r + v_x_inplane * std::cos(t) * r; + this->vertex_push (vstart+c, this->vertexPositions); + c.renormalize(); + this->vertex_push (c, this->vertexNormals); + this->vertex_push (colStart, this->vertexColors); + } + + for (int j = 0; j < segments; j++) { + float t = (float)j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = inplane * std::sin(t) * r_end + v_x_inplane * std::cos(t) * r_end; + this->vertex_push (vend+c, this->vertexPositions); + c.renormalize(); + this->vertex_push (c, this->vertexNormals); + this->vertex_push (colEnd, this->vertexColors); + } + + for (int j = 0; j < segments; j++) { + float t = (float)j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = inplane * std::sin(t) * r_end + v_x_inplane * std::cos(t) * r_end; + this->vertex_push (vend+c, this->vertexPositions); + this->vertex_push (v, this->vertexNormals); + this->vertex_push (colEnd, this->vertexColors); + } + + this->vertex_push (vend, this->vertexPositions); + this->vertex_push (v, this->vertexNormals); + this->vertex_push (colEnd, this->vertexColors); + + int nverts = (segments * 4) + 2; + + uint32_t capMiddle = this->idx; + uint32_t capStartIdx = this->idx + 1u; + uint32_t endMiddle = this->idx + static_cast(nverts) - 1u; + uint32_t endStartIdx = capStartIdx + (3u * segments); + + for (int j = 0; j < segments-1; j++) { + this->indices.push_back (capMiddle); + this->indices.push_back (capStartIdx + j); + this->indices.push_back (capStartIdx + 1 + j); + } + + this->indices.push_back (capMiddle); + this->indices.push_back (capStartIdx + segments - 1); + this->indices.push_back (capStartIdx); + + for (int lsection = 0; lsection < 3; ++lsection) { + capStartIdx = this->idx + 1 + lsection*segments; + endStartIdx = capStartIdx + segments; + for (int j = 0; j < segments; j++) { + this->indices.push_back (capStartIdx + j); + if (j == (segments-1)) { + this->indices.push_back (capStartIdx); + } else { + this->indices.push_back (capStartIdx + 1 + j); + } + this->indices.push_back (endStartIdx + j); + this->indices.push_back (endStartIdx + j); + if (j == (segments-1)) { + this->indices.push_back (endStartIdx); + } else { + this->indices.push_back (endStartIdx + 1 + j); + } + if (j == (segments-1)) { + this->indices.push_back (capStartIdx); + } else { + this->indices.push_back (capStartIdx + j + 1); + } + } + } + + for (int j = 0; j < segments-1; j++) { + this->indices.push_back (endMiddle); + this->indices.push_back (endStartIdx + j); + this->indices.push_back (endStartIdx + 1 + j); + } + this->indices.push_back (endMiddle); + this->indices.push_back (endStartIdx + segments - 1); + this->indices.push_back (endStartIdx); + + this->idx += nverts; + } // end computeFlaredTube with randomly initialized end vertices }; } // namespace mplot diff --git a/mplot/Visual.h b/mplot/Visual.h index be6c9cc4..8c64dfd0 100644 --- a/mplot/Visual.h +++ b/mplot/Visual.h @@ -17,9 +17,16 @@ */ module; +#ifndef _glfw3_h_ // glfw3 has not yet been externally included +# define GLFW_INCLUDE_NONE // Here, we tell GLFW that we will explicitly include GL3/gl3.h and GL/glext.h +# include +#endif // _glfw3_h_ + #include #include +#include + export module mplot.core:visual; export import :win_t; diff --git a/mplot/VisualBase.h b/mplot/VisualBase.h index c350d796..cac15126 100644 --- a/mplot/VisualBase.h +++ b/mplot/VisualBase.h @@ -28,8 +28,7 @@ module; # include #endif -// THIS include is the issue -// #include +#include #include #include @@ -37,18 +36,10 @@ module; #include -// And these -//#include -//#include #include #include -// Use Lode Vandevenne's PNG encoder -#define LODEPNG_NO_COMPILE_DECODER 1 -#define LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS 1 -#include - export module mplot.core:visualbase; import sm.range; @@ -61,6 +52,7 @@ import :win_t; import :textfeatures; import :textgeometry; import :visualcommon; +import :coordarrows; export namespace mplot { @@ -161,17 +153,9 @@ export namespace mplot orthographic }; -#ifdef __APPLE__ - // https://stackoverflow.com/questions/35715579/opengl-created-window-size-twice-as-large - static constexpr double retinaScale = 2; // deals with quadrant issue on osx -#else - static constexpr double retinaScale = 1; // Qt has devicePixelRatio() to get retinaScale. -#endif - // Forward declare VisualModels template class VisualModel; - template class CoordArrows; - template class RodVisual; + //template class CoordArrows; // shouldn't need to now /*! * VisualBase, the mplot::Visual 'scene' base class @@ -403,7 +387,6 @@ export namespace mplot //! Compute position and rotation of coordinate arrows in the bottom left of the screen void positionCoordArrows() { -#if 0 // Find out the location of the bottom left of the screen and make the coord // arrows stay put there. @@ -420,37 +403,32 @@ export namespace mplot v0.set_from ((this->invproj * p0)); // Translate the scene for the CoordArrows such that they sit in a single position on // the screen - this->coordArrows->setSceneTranslation (v0); // argh. method. + this->coordArrows->setSceneTranslation (v0); // Apply rotation to the coordArrows model sm::quaternion svrq = this->sceneview.rotation(); svrq.renormalize(); this->coordArrows->setViewRotation (svrq); -#endif } // Update the coordinate axes labels void updateCoordLabels (const std::string& x_lbl, const std::string& y_lbl, const std::string& z_lbl) { -#if 0 this->coordArrows->clear(); this->coordArrows->x_label = x_lbl; this->coordArrows->y_label = y_lbl; this->coordArrows->z_label = z_lbl; this->coordArrows->initAxisLabels(); this->coordArrows->reinit(); -#endif } // Update the lengths of the CoordArrows that (usually) appear in the corner of the screen void updateCoordLengths (const sm::vec& _lengths, const float _thickness = 1.0f) { -#if 0 this->coordArrows->lengths = _lengths; this->coordArrows->thickness = _thickness; this->coordArrows->clear(); this->coordArrows->initAxisLabels(); this->coordArrows->reinit(); -#endif } // state defaults. All state is false by default @@ -1059,9 +1037,6 @@ export namespace mplot //! Position coordinate arrows on screen. Configurable at mplot::Visual construction. sm::vec coordArrowsOffset = { -0.8f, -0.8f }; - //! Show the user's frame of reference as a model in the scene coords (for debug) - std::unique_ptr> userFrame; - /* * Variables to manage projection and rotation of the scene */ @@ -1461,6 +1436,7 @@ export namespace mplot auto vmi = this->vm.begin(); while (vmi != this->vm.end()) { + // vm_bools comes from VisualModel and would need to be shared if ((*vmi)->flags.test (mplot::vm_bools::compute_bb) && !(*vmi)->flags.test (mplot::vm_bools::twodimensional)) { sm::vec tr_bb_centre = (this->savedSceneview * (*vmi)->get_viewmatrix_bb_centre()).less_one_dim(); diff --git a/mplot/VisualCommon.h b/mplot/VisualCommon.h index 14b6a359..2f320220 100644 --- a/mplot/VisualCommon.h +++ b/mplot/VisualCommon.h @@ -22,6 +22,18 @@ import sm.mat; export namespace mplot { + // State/options flags for VisualModels + enum class vm_bools : uint32_t + { + postVertexInitRequired, + twodimensional, // If true, then this VisualModel should always be viewed in a plane - it's a 2D model + hide, // If true, then calls to VisualModel::render should return + wireframe, // If true, draw in GL's polygon GL_LINES mode (instead of GL_FILL) + instanced, // If true, draw this VisualModel with 'instancing' 1 or more times + show_bb, // If true, draw vertices/indices for the bounding box frame + compute_bb // For some models, it's not useful to compute the bounding box (e.g. coordinate arrows) + }; + // A very simple mesh struct. No textures, materials or owt struct meshgroup { diff --git a/mplot/VisualModelBase.h b/mplot/VisualModelBase.h index 01c6ed6d..c4072677 100644 --- a/mplot/VisualModelBase.h +++ b/mplot/VisualModelBase.h @@ -57,24 +57,12 @@ import sm.flags; namespace mplot { - union float_bytes + union float_bytes // for gltf output { float f; uint8_t bytes[sizeof(float)]; }; - // State/options flags - enum class vm_bools : uint32_t - { - postVertexInitRequired, - twodimensional, // If true, then this VisualModel should always be viewed in a plane - it's a 2D model - hide, // If true, then calls to VisualModel::render should return - wireframe, // If true, draw in GL's polygon GL_LINES mode (instead of GL_FILL) - instanced, // If true, draw this VisualModel with 'instancing' 1 or more times - show_bb, // If true, draw vertices/indices for the bounding box frame - compute_bb // For some models, it's not useful to compute the bounding box (e.g. coordinate arrows) - }; - //! Forward declaration of a Visual class template class VisualBase; diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index 71f2126b..0714e3e6 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -28,6 +28,15 @@ module; #include #include +#include + +// Use Lode Vandevenne's PNG encoder +#define LODEPNG_NO_COMPILE_DECODER 1 +#define LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS 1 +#include + +#include + export module mplot.core:visualownable; import :visualresources; @@ -36,6 +45,13 @@ import :visualbase; export namespace mplot { +#ifdef __APPLE__ + // https://stackoverflow.com/questions/35715579/opengl-created-window-size-twice-as-large + constexpr double retinaScale = 2; // deals with quadrant issue on osx +#else + constexpr double retinaScale = 1; // Qt has devicePixelRatio() to get retinaScale. +#endif + /*! * VisualOwnable - adds multi-context-safe GL calls to the 'scene' base class, VisualBase * @@ -451,23 +467,14 @@ export namespace mplot this->coordArrows = std::make_unique>(); // For CoordArrows, because we don't add via Visual::addVisualModel(), we // have to set the get_shaderprogs function here: - this->bindmodel (this->coordArrows); + this->bindmodel (this->coordArrows); // Won't need bindmodel // And NOW we can proceed to init (lengths, thickness, em size for labels): this->coordArrows->init (sm::vec<>{0.1f, 0.1f, 0.1f}, 1.0f, 0.01f); + + // Prolly don't need the finalize scheme with CoordArrows this->coordArrows->finalize(); // VisualModel::finalize releases context (normally this is the right thing)... this->setContext(); // ...but we've got more work to do, so re-acquire context (if we're managing it) - // Create 'user frame of reference object' - this->userFrame = std::make_unique>(); - this->bindmodel (this->userFrame); - this->userFrame->init (sm::vec{}, - sm::vec{0.0f, 0.0f, -100.0f}, sm::vec{0.1f, 0.1f, 1.0f}, 0.05f, - mplot::colour::turquoise2, mplot::colour::turquoise4); - this->userFrame->face_uy = sm::vec<>::ux(); - this->userFrame->face_uz = sm::vec<>::uy(); - this->userFrame->finalize(); - this->setContext(); // see createCoordArrows() for comments - mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); // Set up the title, which may or may not be rendered diff --git a/mplot/VisualTextModel.h b/mplot/VisualTextModel.h index fa450c50..05088743 100644 --- a/mplot/VisualTextModel.h +++ b/mplot/VisualTextModel.h @@ -39,7 +39,7 @@ import :visualresources; import sm.vec; -namespace mplot +export namespace mplot { //! Forward declaration of a VisualBase class template class VisualBase; From e91c76ad1f53d44c7b5054a27996af18c14c6396 Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 5 Mar 2026 16:55:19 +0000 Subject: [PATCH 012/106] The VisualModel-based coords is now called CoordsVisual --- mplot/CoordsVisual.h | 173 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 mplot/CoordsVisual.h diff --git a/mplot/CoordsVisual.h b/mplot/CoordsVisual.h new file mode 100644 index 00000000..b24e6820 --- /dev/null +++ b/mplot/CoordsVisual.h @@ -0,0 +1,173 @@ +/*! + * \file + * + * Defines a coordinate arrow class based on VisualModel + * + * \author Seb James + * \date 2019 + */ +#pragma once + +#include + +import sm.vec; + +#include +#include +#include + +namespace mplot +{ + //! This class creates the vertices for a set of coordinate arrows to be rendered + //! in a 3-D scene. + template + class CoordsVisual : public VisualModel + { + public: + CoordsVisual() : mplot::VisualModel() {} + CoordsVisual (const sm::vec& offset) : mplot::VisualModel(offset) {} + + //! Must make the boilerplate bindmodel call before calling init() (for text handling) + void init (const sm::vec _lengths, const float _thickness, const float _em) + { + this->compute_bb (false); + this->lengths = _lengths; + this->thickness = _thickness; + this->em = _em; + } + + //! You can call this AS well as the first init overload to set the axis vectors + void init (const sm::vec _x, const sm::vec _y, const sm::vec _z) + { + this->compute_bb (false); + this->x_axis = _x; + this->y_axis = _y; + this->z_axis = _z; + } + + //! Make sure coord arrow colours are ok on the given background colour. Call this *after* finalize. + void setColourForBackground (const std::array& bgcolour) + { + // For now, only worry about the centresphere: + std::array cscol = { 1.0f - bgcolour[0], 1.0f - bgcolour[1], 1.0f - bgcolour[2] }; + if (cscol != this->centresphere_col) { + this->centresphere_col = cscol; + this->reinit(); // sets context, does not release it + + // Give the text labels a suitable, visible colour + if (this->setContext != nullptr) { this->setContext (this->parentVis); } + auto ti = this->texts.begin(); + while (ti != this->texts.end()) { + (*ti)->setVisibleOn (bgcolour); + ti++; + } + if (this->releaseContext != nullptr) { this->releaseContext (this->parentVis); } + } + } + + void initAxisLabels() + { + if (this->em > 0.0f) { + + if (this->setContext != nullptr) { this->setContext (this->parentVis); } // For VisualTextModel + + mplot::TextFeatures tfca(this->em, 48, false, mplot::colour::black, mplot::VisualFont::DVSansItalic); + + // These texts are black by default + sm::vec _offset = this->viewmatrix.translation(); + sm::vec toffset = {}; + toffset = _offset + this->x_axis * this->lengths[0]; + toffset[0] += this->em; + auto vtm1 = this->makeVisualTextModel (tfca); + vtm1->setupText (this->x_label, toffset); + this->texts.push_back (std::move(vtm1)); + toffset = _offset + this->y_axis * this->lengths[1]; + toffset[0] += this->em; + auto vtm2 = this->makeVisualTextModel (tfca); + vtm2->setupText (this->y_label, toffset); + this->texts.push_back (std::move(vtm2)); + toffset = _offset + this->z_axis * this->lengths[2]; + toffset[0] += this->em; + auto vtm3 = this->makeVisualTextModel (tfca); + vtm3->setupText (this->z_label, toffset); + this->texts.push_back (std::move(vtm3)); + + if (this->releaseContext != nullptr) { this->releaseContext (this->parentVis); } + } + } + + //! Initialize vertex buffer objects and vertex array object. + void initializeVertices() + { + this->vertexPositions.clear(); + this->vertexNormals.clear(); + this->vertexColors.clear(); + this->indices.clear(); + this->idx = 0; + + // Draw four spheres to make up the coord frame, with centre at 0,0,0 + sm::vec reloffset = {}; + static constexpr sm::vec zerocoord = { 0.0f, 0.0f, 0.0f }; + this->computeSphere (zerocoord, centresphere_col, this->thickness * this->lengths[0] / 20.0f); + + // x + reloffset = this->x_axis * this->lengths[0]; + this->computeSphere (reloffset, x_axis_col, (this->thickness * this->lengths[0] / 40.0f) * endsphere_size); + this->computeTube (zerocoord, reloffset, x_axis_col, x_axis_col, this->thickness * this->lengths[0] / 80.0f); + if (showneg) { + this->computeTube (zerocoord, -reloffset, x_axis_neg, x_axis_neg, this->thickness * this->lengths[0] / 80.0f); + } + + // y + reloffset = this->y_axis * this->lengths[1]; + this->computeSphere (reloffset, y_axis_col, (this->thickness * this->lengths[0] / 40.0f) * endsphere_size); + this->computeTube (zerocoord, reloffset, y_axis_col, y_axis_col, this->thickness * this->lengths[0] / 80.0f); + if (showneg) { + this->computeTube (zerocoord, -reloffset, y_axis_neg, y_axis_neg, this->thickness * this->lengths[0] / 80.0f); + } + + // z + reloffset = this->z_axis * this->lengths[2]; + this->computeSphere (reloffset, z_axis_col, (this->thickness * this->lengths[0] / 40.0f) * endsphere_size); + this->computeTube (zerocoord, reloffset, z_axis_col, z_axis_col, this->thickness * this->lengths[0] / 80.0f); + if (showneg) { + this->computeTube (zerocoord, -reloffset, z_axis_neg, z_axis_neg, this->thickness * this->lengths[0] / 80.0f); + } + + this->initAxisLabels(); + } + + //! Length multipliers that can be applied to ux, uy and uz + sm::vec lengths = { 1.0f, 1.0f, 1.0f }; + + //! The axes for the coordinate arrows. A simple right handed coordinate system aligned with + //! the 'real' world coordinate system by default. + sm::vec x_axis = { 1.0f, 0.0f, 0.0f }; + sm::vec y_axis = { 0.0f, 1.0f, 0.0f }; + sm::vec z_axis = { 0.0f, 0.0f, 1.0f }; + + //! A thickness scaling factor, to apply to the arrows. + float thickness = 1.0f; + //! a multiplier on the end spheres + float endsphere_size = 1.0f; + //! m size for text labels + float em = 0.0f; + + //! The colours of the arrows, and of the centre sphere (where default of black is suitable + //! for a white background) + std::array centresphere_col = mplot::colour::black; + std::array x_axis_col = mplot::colour::crimson; + std::array y_axis_col = mplot::colour::springgreen2; + std::array z_axis_col = mplot::colour::blue2; + + bool showneg = false; + std::array x_axis_neg = mplot::colour::raspberry; + std::array y_axis_neg = mplot::colour::darkseagreen3; + std::array z_axis_neg = mplot::colour::steelblue3; + + std::string x_label = "X"; + std::string y_label = "Y"; + std::string z_label = "Z"; + }; + +} // namespace mplot From 8c3ed3fcc12f8993f1ec7bd7c9e8067fa3e020cc Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 5 Mar 2026 17:20:53 +0000 Subject: [PATCH 013/106] Still got the circ dep. --- mplot/VisualBase.h | 7 +++---- mplot/VisualModelBase.h | 7 +++++++ mplot/VisualOwnable.h | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/mplot/VisualBase.h b/mplot/VisualBase.h index cac15126..9c1810ce 100644 --- a/mplot/VisualBase.h +++ b/mplot/VisualBase.h @@ -155,7 +155,6 @@ export namespace mplot // Forward declare VisualModels template class VisualModel; - //template class CoordArrows; // shouldn't need to now /*! * VisualBase, the mplot::Visual 'scene' base class @@ -298,7 +297,7 @@ export namespace mplot for (unsigned int modelId = 0; modelId < this->vm.size(); ++modelId) { if (this->vm[modelId].get() == vm_to_follow) { this->followedVM = this->vm[modelId].get(); - this->followedLastViewMatrix = this->followedVM->getViewMatrix(); + this->followedLastViewMatrix = this->followedVM->getViewMatrix(); // COULD pass mat4 break; } } @@ -950,7 +949,7 @@ export namespace mplot if (this->options.test (visual_options::viewFollowsVMTranslations) && this->followedVM != nullptr - && this->followedLastViewMatrix != this->followedVM->getViewMatrix()) { + && this->followedLastViewMatrix != this->followedVM->getViewMatrix()) { // NEED KNOWLEDGE OF VISUALMODEL // Move camera the difference between followedLastViewMatrix and // followedVM->getViewMatrix() in the screen frame of reference. @@ -962,7 +961,7 @@ export namespace mplot this->savedSceneview.pretranslate (fol_screenframe); this->savedSceneview_tr.pretranslate (fol_screenframe); - this->followedLastViewMatrix = this->followedVM->getViewMatrix(); + this->followedLastViewMatrix = this->followedVM->getViewMatrix(); // NEED KNOWLEDGE OF VISUALMODEL } } diff --git a/mplot/VisualModelBase.h b/mplot/VisualModelBase.h index c4072677..be42101c 100644 --- a/mplot/VisualModelBase.h +++ b/mplot/VisualModelBase.h @@ -64,6 +64,13 @@ namespace mplot }; //! Forward declaration of a Visual class + // Right now, models need to know about VisualBase to: + // get shader progs + // set/get context + // + // Could I have a singleton that can do the work and is a separate class so taht VisualModel no + // longer needs to know about VisualBase? Visual registers its identity and the shader programs + // and the singleton could set context based on an id that the VisualModel contains? template class VisualBase; /*! diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index 0714e3e6..241c3324 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -468,6 +468,7 @@ export namespace mplot // For CoordArrows, because we don't add via Visual::addVisualModel(), we // have to set the get_shaderprogs function here: this->bindmodel (this->coordArrows); // Won't need bindmodel + this->coordArrows->glfn = this->glfn; // Just copy in // And NOW we can proceed to init (lengths, thickness, em size for labels): this->coordArrows->init (sm::vec<>{0.1f, 0.1f, 0.1f}, 1.0f, 0.01f); From fa2728df77669d1de9ee107c776d4700d9ca4def Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 5 Mar 2026 19:32:12 +0000 Subject: [PATCH 014/106] The start if an idea to allow VisualModels to get state from VisualResources --- mplot/Visual.h | 3 +++ mplot/VisualBase.h | 3 +++ mplot/VisualModel.h | 38 +++++++++++++++++++++++++++----------- mplot/VisualModelBase.h | 7 ++++++- mplot/VisualResources.h | 26 ++++++++++++++++++++++++-- 5 files changed, 63 insertions(+), 14 deletions(-) diff --git a/mplot/Visual.h b/mplot/Visual.h index 8c64dfd0..78210c29 100644 --- a/mplot/Visual.h +++ b/mplot/Visual.h @@ -105,6 +105,9 @@ export namespace mplot this->init_window(); this->setContext(); // For freetype_init this->freetype_init(); + + uint32_t my_id = mplot::VisualResources::i().register_visual (this); + this->releaseContext(); } diff --git a/mplot/VisualBase.h b/mplot/VisualBase.h index 9c1810ce..e6c4ad60 100644 --- a/mplot/VisualBase.h +++ b/mplot/VisualBase.h @@ -1019,6 +1019,9 @@ export namespace mplot //! The window (and OpenGL context) for this Visual mplot::win_t* window = nullptr; + //! Each window has an ID number, which is passed to the owned VisualModels + uint32_t visual_id = std::numeric_limits::max(); + //! Current window width int window_w = 640; //! Current window height diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index 21d7c22f..6fec06c3 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -30,8 +30,8 @@ import mplot.core; // To know about VisualBase and VisualOwnable static methods namespace mplot { //! Forward declaration of base classes - template class VisualBase; - template class VisualOwnable; + //template class VisualBase; + //template class VisualOwnable; /*! * An OpenGL model class @@ -62,7 +62,10 @@ namespace mplot // Explicitly clear owned VisualTextModels this->texts.clear(); if (this->vbos != nullptr) { - GladGLContext* _glfn = this->get_glfn (this->parentVis); + if (this->visual_id == std::numeric_limits::max()) { + throw std::runtime_error ("visual_id is unset"); + } + GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); _glfn->DeleteBuffers (this->numVBO, this->vbos.get()); _glfn->DeleteVertexArrays (1, &this->vao); } @@ -150,7 +153,10 @@ namespace mplot //! Common code to call after the vertices have been set up. GL has to have been initialised. void postVertexInit() final { - GladGLContext* _glfn = this->get_glfn (this->parentVis); + if (this->visual_id == std::numeric_limits::max()) { + throw std::runtime_error ("visual_id is unset"); + } + GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); // Do gl memory allocation of vertex array once only if (this->vbos == nullptr) { @@ -235,7 +241,11 @@ namespace mplot */ void reinit_buffers() final { - GladGLContext* _glfn = this->get_glfn(this->parentVis); + if (this->visual_id == std::numeric_limits::max()) { + throw std::runtime_error ("visual_id is unset"); + } + GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); + if (this->setContext != nullptr) { this->setContext (this->parentVis); } if (this->flags.test (vm_bools::postVertexInitRequired) == true) { this->postVertexInit(); } @@ -273,7 +283,10 @@ namespace mplot { if (this->setContext != nullptr) { this->setContext (this->parentVis); } if (this->flags.test (vm_bools::postVertexInitRequired) == true) { this->postVertexInit(); } - GladGLContext* _glfn = this->get_glfn(this->parentVis); + if (this->visual_id == std::numeric_limits::max()) { + throw std::runtime_error ("visual_id is unset"); + } + GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); // Now re-set up the VBOs _glfn->BindVertexArray (this->vao); // carefully unbind and rebind this->setupVBO (this->vbos[this->colVBO], this->vertexColors, visgl::colLoc); @@ -295,7 +308,10 @@ namespace mplot GLint prev_shader = 0; - GladGLContext* _glfn = this->get_glfn (this->parentVis); + if (this->visual_id == std::numeric_limits::max()) { + throw std::runtime_error ("visual_id is unset"); + } + GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); _glfn->GetIntegerv (GL_CURRENT_PROGRAM, &prev_shader); // Ensure the correct program is in play for this VisualModel _glfn->UseProgram (this->get_gprog(this->parentVis)); @@ -498,9 +514,6 @@ namespace mplot while (ti != this->texts.end()) { (*ti)->addViewRotation (r); ti++; } } - //! Get the GladGLContext function pointer - std::function*)> get_glfn; - protected: //! A vector of pointers to text models that should be rendered. @@ -511,7 +524,10 @@ namespace mplot { std::size_t sz = dat.size() * sizeof(float); - GladGLContext* _glfn = this->get_glfn(this->parentVis); + if (this->visual_id == std::numeric_limits::max()) { + throw std::runtime_error ("visual_id is unset"); + } + GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); _glfn->BindBuffer (GL_ARRAY_BUFFER, buf); mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); _glfn->BufferData (GL_ARRAY_BUFFER, sz, dat.data(), GL_STATIC_DRAW); diff --git a/mplot/VisualModelBase.h b/mplot/VisualModelBase.h index be42101c..0ec13462 100644 --- a/mplot/VisualModelBase.h +++ b/mplot/VisualModelBase.h @@ -162,7 +162,9 @@ namespace mplot //! Re-create the model - called after updating data void reinit() { - if (this->setContext != nullptr) { this->setContext (this->parentVis); } + if (this->setContext != nullptr) { + this->setContext (this->parentVis); + } // Fixme: Better not to clear, then repeatedly pushback here: this->vertexPositions.clear(); this->vertexNormals.clear(); @@ -785,6 +787,9 @@ namespace mplot // A VisualModel may be given a name std::string name = {}; + // The mplot::Visual ID to which I belong. max means unset. + uint32_t visual_id = std::numeric_limits::max(); + //! The current indices index GLuint idx = 0u; GLuint idx_bb = 0u; diff --git a/mplot/VisualResources.h b/mplot/VisualResources.h index e8a2dd67..cdd10ee2 100644 --- a/mplot/VisualResources.h +++ b/mplot/VisualResources.h @@ -35,14 +35,15 @@ module; export module mplot.core:visualresources; import :visualface; import :visualresourcesbase; +import :visualbase; import sm.vec; export namespace mplot { // Pointers to mplot::VisualBase are used to index font faces - template - class VisualBase; + //template + //class VisualBase; //! Singleton resource class for mplot::Visual scenes. template @@ -133,6 +134,27 @@ export namespace mplot } } + uint32_t register_visual (mplot::VisualBase* vp) + { + uint32_t visual_id = next_visual_id++; + visual_pointers[visual_id] = vp; + return visual_id; + } + + uint32_t next_visual_id = 0; + + // Pointers to Visuals in the program, keyed by a uint32_t ID + std::map*> visual_pointers; + + // A VisualModel can call this, passing in the numeric ID of the context it belongs to and + // this will pass back the correct GL context pointer. + GladGLContext* get_glfn (uint32_t visual_id) + { + visual_pointers[visual_id]->setContext(); + GladGLContext* glfn = visual_pointers[visual_id]->get_glfn (visual_pointers[visual_id]); + return glfn; + } + /*! * We also manage some programm-wide SSBO objects for instanced rendering * VisualResourcesdata in . Reserve n_to_reserve instances of data in the SSBOs. Return the From afe49bf8e00d2eba9c52d9aed9921b249a8df215 Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 5 Mar 2026 21:31:39 +0000 Subject: [PATCH 015/106] More hacking, needto be more awake really --- mplot/CoordArrows.h | 4 +++- mplot/Visual.h | 15 +++------------ mplot/VisualBase.h | 5 ++--- mplot/VisualCommon.h | 2 +- mplot/VisualFace.h | 6 +++++- mplot/VisualFaceBase.h | 2 +- mplot/VisualModel.h | 8 ++------ mplot/VisualModelBase.h | 9 +++++++-- mplot/VisualOwnable.h | 7 +++++++ mplot/VisualResources.h | 15 ++++++++------- mplot/VisualTextModel.h | 15 +++++++++++---- mplot/VisualTextModelBase.h | 12 ++++++++---- 12 files changed, 58 insertions(+), 42 deletions(-) diff --git a/mplot/CoordArrows.h b/mplot/CoordArrows.h index 978393bb..538a40bd 100644 --- a/mplot/CoordArrows.h +++ b/mplot/CoordArrows.h @@ -29,7 +29,9 @@ module; export module mplot.core:coordarrows; -import :visualtextmodel; +import mplot.visualtextmodel; +import :textfeatures; +import :visualfont; import sm.vec; import sm.mat; import sm.flags; diff --git a/mplot/Visual.h b/mplot/Visual.h index 78210c29..a6710188 100644 --- a/mplot/Visual.h +++ b/mplot/Visual.h @@ -30,17 +30,10 @@ module; export module mplot.core:visual; export import :win_t; - export import :visualglfw; - export import :visualownable; - -// Has to be a module partition? -//namespace mplot -//{ -// // With mplot::Visual, we use a GLFW window which is owned by mplot::Visual. -// using win_t = GLFWwindow; -//} +import :visualbase; +import :visualresources; export namespace mplot { @@ -105,9 +98,7 @@ export namespace mplot this->init_window(); this->setContext(); // For freetype_init this->freetype_init(); - - uint32_t my_id = mplot::VisualResources::i().register_visual (this); - + this->visual_id = mplot::VisualResources::i().register_visual (this->glfn); this->releaseContext(); } diff --git a/mplot/VisualBase.h b/mplot/VisualBase.h index e6c4ad60..61025591 100644 --- a/mplot/VisualBase.h +++ b/mplot/VisualBase.h @@ -40,6 +40,8 @@ module; #include +#include + export module mplot.core:visualbase; import sm.range; @@ -153,9 +155,6 @@ export namespace mplot orthographic }; - // Forward declare VisualModels - template class VisualModel; - /*! * VisualBase, the mplot::Visual 'scene' base class * diff --git a/mplot/VisualCommon.h b/mplot/VisualCommon.h index 2f320220..74a74f1f 100644 --- a/mplot/VisualCommon.h +++ b/mplot/VisualCommon.h @@ -13,7 +13,7 @@ module; #include #include -export module mplot.core:visualcommon; +export module mplot.visualcommon; import sm.vec; import sm.range; diff --git a/mplot/VisualFace.h b/mplot/VisualFace.h index 9e9d89d7..bce71c67 100644 --- a/mplot/VisualFace.h +++ b/mplot/VisualFace.h @@ -29,6 +29,9 @@ module; export module mplot.core:visualface; import :visualfacebase; +export import :visualfont; +import mplot.visualcommon; +import sm.vec; export namespace mplot::visgl { @@ -90,7 +93,8 @@ export namespace mplot::visgl // now store character for later use mplot::visgl::CharInfo glchar = { texture, - {static_cast(this->face->glyph->bitmap.width), static_cast(this->face->glyph->bitmap.rows)}, // size + {static_cast(this->face->glyph->bitmap.width), + static_cast(this->face->glyph->bitmap.rows)}, // size {this->face->glyph->bitmap_left, this->face->glyph->bitmap_top}, // bearing static_cast(this->face->glyph->advance.x) // advance }; diff --git a/mplot/VisualFaceBase.h b/mplot/VisualFaceBase.h index a9f79642..cad4263a 100644 --- a/mplot/VisualFaceBase.h +++ b/mplot/VisualFaceBase.h @@ -163,7 +163,7 @@ extern const char __stop_dvsansbi_ttf[]; export module mplot.core:visualfacebase; -import :visualcommon; +import mplot.visualcommon; import :visualfont; import :textfeatures; diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index 6fec06c3..b337e945 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -25,14 +25,8 @@ #include -import mplot.core; // To know about VisualBase and VisualOwnable static methods - namespace mplot { - //! Forward declaration of base classes - //template class VisualBase; - //template class VisualOwnable; - /*! * An OpenGL model class * @@ -81,6 +75,7 @@ namespace mplot throw std::runtime_error ("Can't bind a model, because I am not bound"); } model->set_parent (this->parentVis); +#if 0 model->get_shaderprogs = &mplot::VisualBase::get_shaderprogs; model->get_gprog = &mplot::VisualBase::get_gprog; model->get_tprog = &mplot::VisualBase::get_tprog; @@ -89,6 +84,7 @@ namespace mplot model->setContext = &mplot::VisualBase::set_context; model->releaseContext = &mplot::VisualBase::release_context; +#endif } void set_instance_scale (const float scl) final diff --git a/mplot/VisualModelBase.h b/mplot/VisualModelBase.h index 0ec13462..09907cbd 100644 --- a/mplot/VisualModelBase.h +++ b/mplot/VisualModelBase.h @@ -49,6 +49,9 @@ import sm.range; import sm.algo; import sm.flags; +// Need to import common here +import mplot.visualcommon; + //import mplot.core;// Can I avoid use of this in VisualModelBase? #include @@ -100,11 +103,13 @@ namespace mplot throw std::runtime_error ("Can't bind a model, because I am not bound"); } model->set_parent (this->parentVis); +#if 0 model->get_shaderprogs = &mplot::VisualBase::get_shaderprogs; model->get_gprog = &mplot::VisualBase::get_gprog; model->get_tprog = &mplot::VisualBase::get_tprog; model->setContext = &mplot::VisualBase::set_context; model->releaseContext = &mplot::VisualBase::release_context; +#endif } //! Common code to call after the vertices have been set up. GL has to have been initialised. @@ -808,7 +813,7 @@ namespace mplot //! If drawing with instancing, how many params will be used (these will be cycled through //! per-instance and there may be fewer than instance_count parameters) unsigned int instparam_count = 0; - +#if 0 /*! * A function that will be runtime defined to get_shaderprogs from a pointer to * Visual (saving a boilerplate argument and avoiding that killer circular @@ -830,7 +835,7 @@ namespace mplot std::function&)> insert_instance_data; std::function&, const float, const float)> insert_instparam_data; std::function*)> instanced_needs_update; - +#endif //! Set the scaling matrix for all instances virtual void set_instance_scale (const float scl) = 0; diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index 241c3324..f63786e3 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -39,9 +39,15 @@ module; export module mplot.core:visualownable; +import :visualcommon; import :visualresources; import :visualtextmodel; +import :textgeometry; +import :textfeatures; import :visualbase; +import :coordarrows; + +import sm.vec; export namespace mplot { @@ -128,6 +134,7 @@ export namespace mplot // VisualResources provides font management and GLFW management. Ensure it exists in memory. mplot::VisualResources::i().create(); this->freetype_init(); + this->visual_id = mplot::VisualResources::i().register_visual (this->glfn); } //! GLAD OpenGL function context pointer diff --git a/mplot/VisualResources.h b/mplot/VisualResources.h index cdd10ee2..e490085f 100644 --- a/mplot/VisualResources.h +++ b/mplot/VisualResources.h @@ -34,8 +34,9 @@ module; export module mplot.core:visualresources; import :visualface; +import :visualfont; import :visualresourcesbase; -import :visualbase; +import :textfeatures; import sm.vec; @@ -134,24 +135,24 @@ export namespace mplot } } - uint32_t register_visual (mplot::VisualBase* vp) + uint32_t register_visual (GladGLContext* glfn) { - uint32_t visual_id = next_visual_id++; - visual_pointers[visual_id] = vp; + uint32_t visual_id = this->next_visual_id++; + visual_gladglcontexts[visual_id] = glfn; return visual_id; } uint32_t next_visual_id = 0; // Pointers to Visuals in the program, keyed by a uint32_t ID - std::map*> visual_pointers; + std::map visual_gladglcontexts; // A VisualModel can call this, passing in the numeric ID of the context it belongs to and // this will pass back the correct GL context pointer. GladGLContext* get_glfn (uint32_t visual_id) { - visual_pointers[visual_id]->setContext(); - GladGLContext* glfn = visual_pointers[visual_id]->get_glfn (visual_pointers[visual_id]); + // somehow set context from visual_pointers[visual_id]->setContext(); + GladGLContext* glfn = visual_gladglcontexts[visual_id]; return glfn; } diff --git a/mplot/VisualTextModel.h b/mplot/VisualTextModel.h index 05088743..74c44a8f 100644 --- a/mplot/VisualTextModel.h +++ b/mplot/VisualTextModel.h @@ -31,18 +31,24 @@ module; #include #include -export module mplot.core:visualtextmodel; +export module mplot.visualtextmodel; -import :visualtextmodelbase; +import mplot.visualtextmodelbase; +import mplot.visualcommon; + +// Need these here, they're from core, so will have to be extracted from core. import :visualface; import :visualresources; +import :textfeatures; +import :textgeometry; +import sm.quaternion; import sm.vec; export namespace mplot { //! Forward declaration of a VisualBase class - template class VisualBase; + //template class VisualBase; /*! * Implementation of a separate data-containing model which is used to render text. It is @@ -305,9 +311,10 @@ export namespace mplot } public: +#if 0 //! Get the GladGLContext function pointer std::function*)> get_glfn; - +#endif protected: //! A face for this text. The face is specfied by tfeatures.font mplot::visgl::VisualFace* face = nullptr; diff --git a/mplot/VisualTextModelBase.h b/mplot/VisualTextModelBase.h index 9abe9541..ee94363b 100644 --- a/mplot/VisualTextModelBase.h +++ b/mplot/VisualTextModelBase.h @@ -23,9 +23,9 @@ module; #include #include -export module mplot.core:visualtextmodelbase; +export module mplot.visualtextmodelbase; -import :visualcommon; +import mplot.visualcommon; import :textgeometry; import :textfeatures; @@ -207,11 +207,15 @@ export namespace mplot // A VisualTextModel may be given a name std::string name = "VisualTextModel"; + // The mplot::Visual ID to which I belong. max means unset. + uint32_t visual_id = std::numeric_limits::max(); + //! The colour of the text std::array clr_text = {0.0f, 0.0f, 0.0f}; //! Line spacing, in multiples of the height of an 'h' float line_spacing = 1.4f; - //! Parent Visual +#if 0 + //! Parent Visual (to be replaced with a uint32_t visual_id) mplot::VisualBase* parentVis = nullptr; /*! @@ -233,7 +237,7 @@ export namespace mplot std::function&)> insert_instance_data; std::function&, const float, const float)> insert_instparam_data; std::function*)> instanced_needs_update; - +#endif //! Setter for the parent pointer, parentVis void set_parent (mplot::VisualBase* _vis) { From 8bdb664f6124816806aa9ac39538e7f4a3a29f85 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 6 Mar 2026 09:18:19 +0000 Subject: [PATCH 016/106] Removing base classes where unnecessary --- examples/CMakeLists.txt | 8 - mplot/TextFeatures.h | 4 +- mplot/TextGeometry.h | 2 +- mplot/VisualBase.h | 1745 ---------------- mplot/VisualFace.h | 409 +++- mplot/VisualFaceBase.h | 419 ---- mplot/VisualFont.h | 2 +- mplot/VisualModel.h | 3718 ++++++++++++++++++++++++++++++++--- mplot/VisualModelBase.h | 3330 ------------------------------- mplot/VisualOwnable.h | 1654 +++++++++++++++- mplot/VisualResources.h | 97 +- mplot/VisualResourcesBase.h | 100 - mplot/VisualTextModel.h | 337 +++- mplot/VisualTextModelBase.h | 328 --- 14 files changed, 5894 insertions(+), 6259 deletions(-) delete mode 100644 mplot/VisualBase.h delete mode 100644 mplot/VisualFaceBase.h delete mode 100644 mplot/VisualModelBase.h delete mode 100644 mplot/VisualResourcesBase.h delete mode 100644 mplot/VisualTextModelBase.h diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 38b35a85..394e6b60 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -25,20 +25,16 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra ${PROJECT_SOURCE_DIR}/maths/sm/flags ${PROJECT_SOURCE_DIR}/maths/sm/centroid - ${PROJECT_SOURCE_DIR}/mplot/VisualBase.h ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h ${PROJECT_SOURCE_DIR}/mplot/Visual.h ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFaceBase.h ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h - ${PROJECT_SOURCE_DIR}/mplot/VisualResourcesBase.h ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualTextModelBase.h ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h ${PROJECT_SOURCE_DIR}/mplot/win_t.h ${PROJECT_SOURCE_DIR}/mplot/core.ixx @@ -51,20 +47,16 @@ target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE ${PROJECT_SOURCE_DIR}/mplot/core.ixx ${PROJECT_SOURCE_DIR}/mplot/win_t.h ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h - ${PROJECT_SOURCE_DIR}/mplot/VisualBase.h ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h ${PROJECT_SOURCE_DIR}/mplot/Visual.h ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFaceBase.h ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h - ${PROJECT_SOURCE_DIR}/mplot/VisualResourcesBase.h ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualTextModelBase.h ${PROJECT_SOURCE_DIR}/maths/sm/flags ${PROJECT_SOURCE_DIR}/maths/sm/algo ${PROJECT_SOURCE_DIR}/maths/sm/range diff --git a/mplot/TextFeatures.h b/mplot/TextFeatures.h index e25bea57..f358675e 100644 --- a/mplot/TextFeatures.h +++ b/mplot/TextFeatures.h @@ -3,9 +3,9 @@ module; #include #include -export module mplot.core:textfeatures; +export module mplot.textfeatures; -import :visualfont; +import mplot.visualfont; export namespace mplot { diff --git a/mplot/TextGeometry.h b/mplot/TextGeometry.h index 72be198f..6211b429 100644 --- a/mplot/TextGeometry.h +++ b/mplot/TextGeometry.h @@ -1,4 +1,4 @@ -export module mplot.core:textgeometry; +export module mplot.textgeometry; export namespace mplot { diff --git a/mplot/VisualBase.h b/mplot/VisualBase.h deleted file mode 100644 index 61025591..00000000 --- a/mplot/VisualBase.h +++ /dev/null @@ -1,1745 +0,0 @@ -/*! - * \file - * - * Awesome graphics code for high performance graphing and visualisation. This is the abstract base - * class for the Visual scene classes (it contains common functionality, but no GL) - * - * \author Seb James - * \date March 2025 - */ -module; - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#if defined __gl3_h_ || defined __gl_h_ -// GL headers have been externally included -#else -// Include GLAD header -# define GLAD_GL_IMPLEMENTATION -# include -#endif - -#include - -#include -#include -#include - -#include - -#include - -#include - -#include - -export module mplot.core:visualbase; - -import sm.range; -import sm.flags; -import sm.quaternion; -import sm.mat; -import sm.vec; - -import :win_t; -import :textfeatures; -import :textgeometry; -import :visualcommon; -import :coordarrows; - -export namespace mplot -{ - //! Here are our boolean state flags - enum class visual_state : uint32_t - { - readyToFinish, - //! paused can be set true so that pauseOpen() can be used to display the window mid-simulation - paused, - //! If you set this to true, then the mouse movements won't change scenetrans or rotation. - sceneLocked, - //! When true, cursor movements induce rotation of scene - rotateMode, - //! When true, rotations about the third axis are possible. - rotateModMode, - //! When true, cursor movements induce translation of scene - translateMode, - //! We are scrolling (and so we will need to zero scenetrans_delta after enacting the change) - scrolling, - //! True means that at least one of our VisualModels is an instanced rendering model - haveInstanced, - //! When true, the instanced data SSBO needs to be copied to the GPU - instancedNeedsUpdate, - //! Left mouse button is down - mouseButtonLeftPressed, - //! Right mouse button is down - mouseButtonRightPressed - }; - - //! Boolean options - similar to state, but more likely to be modified by client code - enum class visual_options : uint32_t - { - //! Set true to disable the 'X' button on the Window from exiting the program - preventWindowCloseWithButton, - //! Set to true to show the coordinate arrows - showCoordArrows, - //! If true, then place the coordinate arrows at the origin of the scene, rather than offset. - coordArrowsInScene, - //! Show user frame of reference (for debug) - showUserFrame, - //! Set to true to show the title text within the scene - showTitle, - //! Set true to output some user information to stdout (e.g. user requested quit) - userInfoStdout, - //! If true, output mplot version to stdout - versionStdout, - //! If true (the default), then call swapBuffers() at the end of render() - renderSwapsBuffers, - /*! - * If true, rotation is about the scene origin, rather than the most central VisualModel. - * - * If false, the system finds the most central VisualModel, and rotates about the centroid - * of the bounding box that surrounds that VisualModel. - */ - rotateAboutSceneOrigin, - /*! - * If true, horizontal mouse movements rotate the scene about a chosen vertical axis, and - * vertical mouse movements rotate the vertical axis about the bottom of the user's - * viewport. This will be familiar to Blender users. Additionally, if the ctrl-modified - * mouse move mode is enabled, the scene is tilted about the axis coming out of the - * viewport. - * - * If false, horizontal mouse movements rotate the scene about the vertical axis of the - * user's viewport, vertcial mouse movements rotate the scene about the horizontal axis of - * the viewport, and ctrl-modified mouse movements rotate the scene about the axis coming - * out of the viewport. This was the original scene navigation scheme in mathplot and before - * that in morphologica. - */ - rotateAboutVertical, - /*! - * If true, write bounding boxes out to a json file /tmp/mathplot_bounding_boxes.json that - * can be read with the show_boundingboxes program - */ - boundingBoxesToJson, - //! If true, draw all the bounding boxes around the VisualModels - showBoundingBoxes, - /*! - * If true, then turn on the bounding box for the VM about which we are rotating and turn - * the others off (ignoring the value of 'showBoundingBoxes') - */ - highlightRotationVM, - /*! - * If true, the view of the scene follows a model translation (one of the VisualModels in - * the scene has to be nominated as the 'model to follow'. Useful for top-down views. The - * selected model to follow is in a member attribute followedModel - */ - viewFollowsVMTranslations, - /*! - * The view 'camera' rotates with the selected VM (followedModel) - */ - viewFollowsVMBehind, - }; - - //! Whether to render with perspective or orthographic - enum class perspective_type : uint32_t - { - perspective, - orthographic - }; - - /*! - * VisualBase, the mplot::Visual 'scene' base class - * - * A base class for visualising computational models on an OpenGL screen. - * - * This contains code that is not OpenGL dependent. OpenGL dependent code is in - * VisualOwnable - * - * For mathplot program using GLFW windows, Inheritance chain will either be: - * - * VisualBase -> VisualOwnable -> Visual - * - * mathplot based widgets, such as the Qt compatible mplot::qt::viswidget have this: - * - * VisualBase -> VisualOwnable -> viswidget - * - * \tparam glver The OpenGL version, encoded as a single int (see mplot::gl::version) - */ - template - class VisualBase - { - public: - /*! - * Default constructor is used when incorporating Visual inside another object - * such as a QWidget. We have to wait on calling init functions until an OpenGL - * environment is guaranteed to exist. - */ - VisualBase() { - this->sceneview.translate (this->scenetrans_default); - this->sceneview_tr.translate (this->scenetrans_default); - } - - /*! - * Construct a new visualiser. The rule is 1 window to one Visual object. So, this creates a - * new window and a new OpenGL context. - */ - VisualBase (const int _width, const int _height, const std::string& _title, const bool _version_stdout = true) - : window_w(_width) - , window_h(_height) - , title(_title) - { - this->sceneview.translate (this->scenetrans_default); - this->sceneview_tr.translate (this->scenetrans_default); - this->options.set (visual_options::versionStdout, _version_stdout); - this->init_gl(); // abstract - } - - //! Deconstruct gl memory/context - virtual void deconstructCommon() = 0; - - // We do not manage OpenGL context, but it is simpler to have a no-op set/releaseContext for some of the GL setup functions - virtual void setContext() {} // no op here - virtual void releaseContext() {} // no op here - virtual void setSwapInterval() {} // no op here - virtual void swapBuffers() {} // no op here - - // A callback friendly wrapper for setContext - static void set_context (mplot::VisualBase* _v) { _v->setContext(); }; - // A callback friendly wrapper for releaseContext - static void release_context (mplot::VisualBase* _v) { _v->releaseContext(); }; - - // Public init that is given a context (window or widget) and then sets up the - // VisualResource, shaders and so on. - void init (mplot::win_t* ctx) - { - this->window = ctx; - this->init_resources(); - this->init_gl(); - } - - protected: - virtual void freetype_init() = 0; // does this need to be here? - - public: - // Do one-time init of resources (such as freetypes, windowing system etc) - virtual void init_resources() = 0; - - //! Take a screenshot of the window. Return vec containing width * height or {-1, -1} on - //! failure. Set transparent_bg to get a transparent background. - virtual sm::vec saveImage (const std::string& img_filename, const bool transparent_bg = false) = 0; - - /*! - * Set up the passed-in VisualModel (or indeed, VisualTextModel) with functions that need access to Visual attributes. - */ - template - void bindmodel (std::unique_ptr& model) - { - model->set_parent (this); - model->get_shaderprogs = &mplot::VisualBase::get_shaderprogs; - model->get_gprog = &mplot::VisualBase::get_gprog; - model->get_tprog = &mplot::VisualBase::get_tprog; - model->instanced_needs_update = &mplot::VisualBase::instanced_needs_update; - } - - /*! - * Add a VisualModel to the scene as a unique_ptr. The Visual object takes ownership of the - * unique_ptr. The index into Visual::vm is returned. - */ - template - unsigned int addVisualModelId (std::unique_ptr& model) - { - std::unique_ptr> vmp = std::move(model); - if (vmp->instanced()) { this->state.set (visual_state::haveInstanced, true); } - this->vm.push_back (std::move(vmp)); - unsigned int rtn = (this->vm.size()-1); - return rtn; - } - /*! - * Add a VisualModel to the scene as a unique_ptr. The Visual object takes ownership of the - * unique_ptr. A non-owning pointer to the model is returned. - */ - template - T* addVisualModel (std::unique_ptr& model) - { - std::unique_ptr> vmp = std::move(model); - if (vmp->instanced()) { this->state.set (visual_state::haveInstanced, true); } - this->vm.push_back (std::move(vmp)); - return static_cast(this->vm.back().get()); - } - - /*! - * Test the pointer vmp. Return vmp if it is owned by a unique_ptr in - * Visual::vm. If it is not present, return nullptr. - */ - const mplot::VisualModel* validVisualModel (const mplot::VisualModel* vmp) const - { - const mplot::VisualModel* rtn = nullptr; - for (unsigned int modelId = 0; modelId < this->vm.size(); ++modelId) { - if (this->vm[modelId].get() == vmp) { - rtn = vmp; - break; - } - } - return rtn; - } - - void setFollowedVM (const mplot::VisualModel* vm_to_follow) - { - for (unsigned int modelId = 0; modelId < this->vm.size(); ++modelId) { - if (this->vm[modelId].get() == vm_to_follow) { - this->followedVM = this->vm[modelId].get(); - this->followedLastViewMatrix = this->followedVM->getViewMatrix(); // COULD pass mat4 - break; - } - } - } - - /*! - * VisualModel Getter - * - * For the given \a modelId, return a (non-owning) pointer to the visual model. - * - * \return VisualModel pointer - */ - mplot::VisualModel* getVisualModel (unsigned int modelId) { return (this->vm[modelId].get()); } - - //! Remove the VisualModel with ID \a modelId from the scene. - void removeVisualModel (unsigned int modelId) { this->vm.erase (this->vm.begin() + modelId); } - - //! Remove the VisualModel whose pointer matches the VisualModel* vmp - void removeVisualModel (mplot::VisualModel* vmp) - { - unsigned int modelId = 0; - bool found_model = false; - for (modelId = 0; modelId < this->vm.size(); ++modelId) { - if (this->vm[modelId].get() == vmp) { - found_model = true; - break; - } - } - if (found_model == true) { this->vm.erase (this->vm.begin() + modelId); } - } - - void clear () { this->vm.clear(); } - - void set_cursorpos (double _x, double _y) { this->cursorpos = {static_cast(_x), static_cast(_y)}; } - - //! A callback function - static void callback_render (mplot::VisualBase* _v) { _v->render(); }; - - //! Render the scene - virtual void render() noexcept = 0; - - //! Compute a translation vector for text position, using Visual::text_z. - sm::vec textPosition (const sm::vec p0_coord) - { - // For the depth at which a text object lies, use this->text_z. Use forward - // projection to determine the correct z coordinate for the inverse - // projection. - sm::vec point = { 0.0f, 0.0f, this->text_z, 1.0f }; - sm::vec pp = this->projection * point; - float coord_z = pp[2]/pp[3]; // divide by pp[3] is divide by/normalise by 'w'. - // Construct the point for the location of the text - sm::vec p0 = { p0_coord.x(), p0_coord.y(), coord_z, 1.0f }; - // Inverse project the point - sm::vec v0; - v0.set_from (this->invproj * p0); - return v0; - } - - //! The OpenGL shader programs have an integer ID and are stored in a simple struct. There's - //! one for graphical objects and a text shader program, which uses textures to draw text on - //! quads. - mplot::visgl::visual_shaderprogs shaders; - //! Which shader is active for graphics shading. In practice, this is always 'projection2d' - mplot::visgl::graphics_shader_type active_gprog = mplot::visgl::graphics_shader_type::none; - //! Stores the info required to load the 2D projection shader - std::vector proj2d_shader_progs; - //! Stores the info required to load the text shader - std::vector text_shader_progs; - - // These static functions will be set as callbacks in each VisualModel object. - static mplot::visgl::visual_shaderprogs get_shaderprogs (mplot::VisualBase* _v) { return _v->shaders; }; - static GLuint get_gprog (mplot::VisualBase* _v) { return _v->shaders.gprog; }; - static GLuint get_tprog (mplot::VisualBase* _v) { return _v->shaders.tprog; }; - - static void instanced_needs_update (mplot::VisualBase* _v) { _v->instancedNeedsUpdate (true); } - - //! The colour of ambient and diffuse light sources - sm::vec light_colour = { 1.0f, 1.0f, 1.0f }; - //! Strength of the ambient light - float ambient_intensity = 1.0f; - //! Position of a diffuse light source - sm::vec diffuse_position = { 5.0f, 5.0f, 15.0f }; - //! Strength of the diffuse light source - float diffuse_intensity = 0.0f; - - //! Compute position and rotation of coordinate arrows in the bottom left of the screen - void positionCoordArrows() - { - // Find out the location of the bottom left of the screen and make the coord - // arrows stay put there. - - // Add the depth at which the object lies. Use forward projection to determine the - // correct z coordinate for the inverse projection. This assumes only one object. - sm::vec point = { 0.0f, 0.0f, this->sceneview[14], 1.0f }; // sceneview[14] is 'scenetrans.z' - sm::vec pp = this->projection * point; - float coord_z = pp[2]/pp[3]; // divide by pp[3] is divide by/normalise by 'w'. - - // Construct the point for the location of the coord arrows - sm::vec p0 = { this->coordArrowsOffset.x(), this->coordArrowsOffset.y(), coord_z, 1.0f }; - // Inverse project - sm::vec v0; - v0.set_from ((this->invproj * p0)); - // Translate the scene for the CoordArrows such that they sit in a single position on - // the screen - this->coordArrows->setSceneTranslation (v0); - // Apply rotation to the coordArrows model - sm::quaternion svrq = this->sceneview.rotation(); - svrq.renormalize(); - this->coordArrows->setViewRotation (svrq); - } - - // Update the coordinate axes labels - void updateCoordLabels (const std::string& x_lbl, const std::string& y_lbl, const std::string& z_lbl) - { - this->coordArrows->clear(); - this->coordArrows->x_label = x_lbl; - this->coordArrows->y_label = y_lbl; - this->coordArrows->z_label = z_lbl; - this->coordArrows->initAxisLabels(); - this->coordArrows->reinit(); - } - - // Update the lengths of the CoordArrows that (usually) appear in the corner of the screen - void updateCoordLengths (const sm::vec& _lengths, const float _thickness = 1.0f) - { - this->coordArrows->lengths = _lengths; - this->coordArrows->thickness = _thickness; - this->coordArrows->clear(); - this->coordArrows->initAxisLabels(); - this->coordArrows->reinit(); - } - - // state defaults. All state is false by default - constexpr sm::flags state_defaults() - { - sm::flags _state; - return _state; - } - - // State flags - sm::flags state = state_defaults(); - - // Options defaults. - constexpr sm::flags options_defaults() - { - sm::flags _options; - // Only with ImGui do we manually swap buffers, so this is true by default: - _options.set (visual_options::renderSwapsBuffers); - // For now, default to rotating about scene origin, as we ever did (Ctrl-k to change) - _options.set (visual_options::rotateAboutSceneOrigin); - // Also, for now, keep the Blender-like 'rotateAboutVertical' as a non-default option (Ctrl-d to change) - _options.set (visual_options::rotateAboutVertical, false); - - return _options; - } - - // Option flags - sm::flags options = options_defaults(); - - //! Returns true when the program has been flagged to end - bool readyToFinish() const { return this->state.test (visual_state::readyToFinish); } - - //! Returns true if we are in the paused state - bool paused() const { return this->state.test (visual_state::paused); } - - //! True if one of our added VisualModels is an instanced model - bool haveInstanced() const { return this->state.test (visual_state::haveInstanced); } - - //! Does our instanced data need to be pushed over to the GPU during render()? - bool instancedNeedsUpdate() const { return this->state.test (visual_state::instancedNeedsUpdate); } - void instancedNeedsUpdate (const bool val) { this->state.set (visual_state::instancedNeedsUpdate, val); } - - /* - * User-settable projection values for the near clipping distance, the far clipping distance - * and the field of view of the camera. - */ - - float zNear = 0.001f; - float zFar = 300.0f; - float fov = 30.0f; - - //! Time constants for the way the camera moves between a follow-me view and a - //! drone-view. One for translation, the other for rotation. - float trans_tc = 0.09f; - //! Rotational time constant - float rotn_tc = trans_tc; - - //! Which was is up in the scene? In OpenGL it's usually y, but may be changed to z in some cases - sm::vec scene_up = sm::vec::uy(); - //! Which way goes to the 'right' across the screen? Usually x - sm::vec scene_right = sm::vec::ux(); - //! Out of the screen? - sm::vec scene_out = sm::vec::uz(); - - //! Setter for visual_options::showCoordArrows - void showCoordArrows (const bool val) { this->options.set (visual_options::showCoordArrows, val); } - - //! If true, then place the coordinate arrows at the origin of the scene, rather than offset. - void coordArrowsInScene (const bool val) { this->options.set (visual_options::coordArrowsInScene, val); } - - //! Rotate about the nearest VisualModel? - void rotateAboutNearest (const bool val) - { this->options.set (mplot::visual_options::rotateAboutSceneOrigin, (val ? false : true)); } - - //! Rotate about a vertical axis in the scene? - void rotateAboutVertical (const bool val) { this->options.set (visual_options::rotateAboutVertical, val); } - - //! Set to true to show the title text within the scene - void showTitle (const bool val) { this->options.set (visual_options::showTitle, val); } - - //! Set true to output some user information to stdout (e.g. user requested quit) - void userInfoStdout (const bool val) { this->options.set (visual_options::userInfoStdout, val); } - - //! You can call this with val==false to manage exactly when you call the swapBuffer() method (for ImGui programs) - void renderSwapsBuffers (const bool val) { this->options.set (visual_options::renderSwapsBuffers, val); } - - //! How big should the steps in scene translation be when scrolling? - float scenetrans_stepsize = 0.02f; - - //! If you set this to true, then the mouse movements won't change scenetrans or rotation. - void sceneLocked (const bool val) { this->state.set (visual_state::sceneLocked, val); } - - //! Show bounding boxes? - void showBoundingBoxes (const bool val) { this->options.set (visual_options::showBoundingBoxes, val); } - - //! Highlight (with a bounding box) the VisualModel being used for rotation? - void highlightRotationVM (const bool val) { this->options.set (visual_options::highlightRotationVM, val); } - - //! Can change this to orthographic - perspective_type ptype = perspective_type::perspective; - - //! Orthographic screen left-bottom coordinate (you can change these to encapsulate your models) - sm::vec ortho_lb = { -1.3f, -1.0f }; - //! Orthographic screen right-top coordinate - sm::vec ortho_rt = { 1.3f, 1.0f }; - - //! The background colour; white by default. - std::array bgcolour = { 1.0f, 1.0f, 1.0f, 0.5f }; - - /* - * User can directly set bgcolour for any background colour they like, but - * here are convenience functions: - */ - - //! Set a white background colour for the Visual scene - void backgroundWhite() { this->bgcolour = { 1.0f, 1.0f, 1.0f, 0.5f }; } - //! Set a black background colour for the Visual scene - void backgroundBlack() { this->bgcolour = { 0.0f, 0.0f, 0.0f, 0.0f }; } - - //! Set sceneview and sceneview_tr back to scenetrans_default - void reset_sceneviews_to_scenetrans_default() - { - this->sceneview.set_identity(); - this->sceneview.translate (this->scenetrans_default); - this->sceneview_tr.set_identity(); - this->sceneview_tr.translate (this->scenetrans_default); - this->d_to_rotation_centre = -this->scenetrans_default[2]; - } - - //! Set the scene's x and y values at the same time. - void setSceneTransXY (const float _x, const float _y) - { - this->scenetrans_default[0] = _x; - this->scenetrans_default[1] = _y; - this->reset_sceneviews_to_scenetrans_default(); - } - //! Set the scene's y value. Use this to shift your scene objects left or right - void setSceneTransX (const float _x) - { - this->scenetrans_default[0] = _x; - this->reset_sceneviews_to_scenetrans_default(); - } - //! Set the scene's y value. Use this to shift your scene objects up and down - void setSceneTransY (const float _y) - { - this->scenetrans_default[1] = _y; - this->reset_sceneviews_to_scenetrans_default(); - } - //! Set the scene's z value. Use this to bring the 'camera' closer to your scene - //! objects (that is, your mplot::VisualModel objects). - void setSceneTransZ (const float _z) - { - if (_z > 0.0f) { - std::cerr << "WARNING setSceneTransZ(): Normally, the default z value is negative.\n"; - } - this->scenetrans_default[2] = _z; - this->reset_sceneviews_to_scenetrans_default(); - } - void setSceneTrans (float _x, float _y, float _z) - { - if (_z > 0.0f) { - std::cerr << "WARNING setSceneTrans(): Normally, the default z value is negative.\n"; - } - - this->scenetrans_default[0] = _x; - this->scenetrans_default[1] = _y; - this->scenetrans_default[2] = _z; - this->reset_sceneviews_to_scenetrans_default(); - } - void setSceneTrans (const sm::vec& _xyz) - { - if (_xyz[2] > 0.0f) { - std::cerr << "WARNING setSceneTrans(vec<>&): Normally, the default z value is negative.\n"; - } - this->scenetrans_default = _xyz; - this->reset_sceneviews_to_scenetrans_default(); - } - - void setSceneRotation (const sm::quaternion& _rotn) - { - this->rotation_default = _rotn; - this->sceneview.rotate (_rotn); - } - - // What is the scene view's current rotation quaternion? - sm::quaternion getSceneRotation() const { return this->sceneview.rotation(); } - // What is the scene view's current translation? - sm::vec getSceneTranslation() const { return this->sceneview.translation(); } - - void lightingEffects (const bool effects_on = true) - { - this->ambient_intensity = effects_on ? 0.4f : 1.0f; - this->diffuse_intensity = effects_on ? 0.6f : 0.0f; - } - - //! Save all the VisualModels in this Visual out to a GLTF format file - virtual void savegltf (const std::string& gltf_file) - { - std::ofstream fout; - fout.open (gltf_file, std::ios::out|std::ios::trunc); - if (!fout.is_open()) { throw std::runtime_error ("Visual::savegltf(): Failed to open file for writing"); } - fout << "{\n \"scenes\" : [ { \"nodes\" : [ "; - for (std::size_t vmi = 0u; vmi < this->vm.size(); ++vmi) { - fout << vmi << (vmi < this->vm.size()-1 ? ", " : ""); - } - fout << " ] } ],\n"; - - fout << " \"nodes\" : [\n"; - // for loop over VisualModels "mesh" : 0, etc - for (std::size_t vmi = 0u; vmi < this->vm.size(); ++vmi) { - fout << " { \"mesh\" : " << vmi - << ", \"translation\" : " << this->vm[vmi]->translation_str() - << (vmi < this->vm.size()-1 ? " },\n" : " }\n"); - } - fout << " ],\n"; - - fout << " \"meshes\" : [\n"; - // for each VisualModel: - for (std::size_t vmi = 0u; vmi < this->vm.size(); ++vmi) { - fout << " { "; - if (!this->vm[vmi]->name.empty()) { - fout << "\"name\" : \"" << this->vm[vmi]->name << "\", "; - } - fout << "\"primitives\" : [ { \"attributes\" : { \"POSITION\" : " << 1+vmi*4 - << ", \"COLOR_0\" : " << 2+vmi*4 - << ", \"NORMAL\" : " << 3+vmi*4 << " }, \"indices\" : " << vmi*4 << ", \"material\": 0 } ] }" - << (vmi < this->vm.size()-1 ? ",\n" : "\n"); - } - fout << " ],\n"; - - fout << " \"buffers\" : [\n"; - for (std::size_t vmi = 0u; vmi < this->vm.size(); ++vmi) { - // indices - fout << " {\"uri\" : \"data:application/octet-stream;base64," << this->vm[vmi]->indices_base64() << "\", " - << "\"byteLength\" : " << this->vm[vmi]->indices_bytes() << "},\n"; - // pos - fout << " {\"uri\" : \"data:application/octet-stream;base64," << this->vm[vmi]->vpos_base64() << "\", " - << "\"byteLength\" : " << this->vm[vmi]->vpos_bytes() << "},\n"; - // col - fout << " {\"uri\" : \"data:application/octet-stream;base64," << this->vm[vmi]->vcol_base64() << "\", " - << "\"byteLength\" : " << this->vm[vmi]->vcol_bytes() << "},\n"; - // norm - fout << " {\"uri\" : \"data:application/octet-stream;base64," << this->vm[vmi]->vnorm_base64() << "\", " - << "\"byteLength\" : " << this->vm[vmi]->vnorm_bytes() << "}"; - fout << (vmi < this->vm.size()-1 ? ",\n" : "\n"); - } - fout << " ],\n"; - - fout << " \"bufferViews\" : [\n"; - for (std::size_t vmi = 0u; vmi < this->vm.size(); ++vmi) { - // indices - fout << " { "; - fout << "\"buffer\" : " << vmi*4 << ", "; - fout << "\"byteOffset\" : 0, "; - fout << "\"byteLength\" : " << this->vm[vmi]->indices_bytes() << ", "; - fout << "\"target\" : 34963 "; - fout << " },\n"; - // vpos - fout << " { "; - fout << "\"buffer\" : " << 1+vmi*4 << ", "; - fout << "\"byteOffset\" : 0, "; - fout << "\"byteLength\" : " << this->vm[vmi]->vpos_bytes() << ", "; - fout << "\"target\" : 34962 "; - fout << " },\n"; - // vcol - fout << " { "; - fout << "\"buffer\" : " << 2+vmi*4 << ", "; - fout << "\"byteOffset\" : 0, "; - fout << "\"byteLength\" : " << this->vm[vmi]->vcol_bytes() << ", "; - fout << "\"target\" : 34962 "; - fout << " },\n"; - // vnorm - fout << " { "; - fout << "\"buffer\" : " << 3+vmi*4 << ", "; - fout << "\"byteOffset\" : 0, "; - fout << "\"byteLength\" : " << this->vm[vmi]->vnorm_bytes() << ", "; - fout << "\"target\" : 34962 "; - fout << " }"; - fout << (vmi < this->vm.size()-1 ? ",\n" : "\n"); - } - fout << " ],\n"; - - fout << " \"accessors\" : [\n"; - for (std::size_t vmi = 0u; vmi < this->vm.size(); ++vmi) { - this->vm[vmi]->computeVertexMaxMins(); - // indices - fout << " { "; - fout << "\"bufferView\" : " << vmi*4 << ", "; - fout << "\"byteOffset\" : 0, "; - // 5123 unsigned short, 5121 unsigned byte, 5125 unsigned int, 5126 float: - fout << "\"componentType\" : 5125, "; - fout << "\"type\" : \"SCALAR\", "; - fout << "\"count\" : " << this->vm[vmi]->indices_size(); - fout << "},\n"; - // vpos - fout << " { "; - fout << "\"bufferView\" : " << 1+vmi*4 << ", "; - fout << "\"byteOffset\" : 0, "; - fout << "\"componentType\" : 5126, "; - fout << "\"type\" : \"VEC3\", "; - fout << "\"count\" : " << this->vm[vmi]->vpos_size()/3; - // vertex position requires max/min to be specified in the gltf format - fout << ", \"max\" : " << this->vm[vmi]->vpos_max() << ", "; - fout << "\"min\" : " << this->vm[vmi]->vpos_min(); - fout << " },\n"; - // vcol - fout << " { "; - fout << "\"bufferView\" : " << 2+vmi*4 << ", "; - fout << "\"byteOffset\" : 0, "; - fout << "\"componentType\" : 5126, "; - fout << "\"type\" : \"VEC3\", "; - fout << "\"count\" : " << this->vm[vmi]->vcol_size()/3; - fout << "},\n"; - // vnorm - fout << " { "; - fout << "\"bufferView\" : " << 3+vmi*4 << ", "; - fout << "\"byteOffset\" : 0, "; - fout << "\"componentType\" : 5126, "; - fout << "\"type\" : \"VEC3\", "; - fout << "\"count\" : " << this->vm[vmi]->vnorm_size()/3; - fout << "}"; - fout << (vmi < this->vm.size()-1 ? ",\n" : "\n"); - } - fout << " ],\n"; - - // Default material is single sided, so make it double sided - fout << " \"materials\" : [ { \"doubleSided\" : true } ],\n"; - - fout << " \"asset\" : {\n" - << " \"generator\" : \"https://github.com/sebsjames/mathplot: mplot::Visual::savegltf() (ver " - << mplot::version_string() << ")\",\n" - << " \"version\" : \"2.0\"\n" // This version is the *glTF* version. - << " }\n"; - fout << "}\n"; - fout.close(); - } - - void set_winsize (int _w, int _h) { this->window_w = _w; this->window_h = _h; } - - // Accessing std::vector>> vm; from external code - std::vector>>::const_iterator next_vm_accessor; - void init_vm_accessor() { this->next_vm_accessor = this->vm.begin(); } - mplot::VisualModel* get_next_vm_accessor() - { - mplot::VisualModel* cvm = nullptr; - if (this->next_vm_accessor != this->vm.end()) { - cvm = (*this->next_vm_accessor).get(); - this->next_vm_accessor++; - } - return cvm; - } - - protected: - - //! Set up a perspective projection based on window width and height. Not public. - void setPerspective() - { - // Calculate aspect ratio - float aspect = static_cast(this->window_w) / static_cast(this->window_h ? this->window_h : 1); - // Set perspective projection - this->projection = sm::mat::perspective (this->fov, aspect, this->zNear, this->zFar); - // Compute the inverse projection matrix - this->invproj = this->projection.inverse(); - } - - /*! - * Set an orthographic projection. This is not a public function. To choose orthographic - * projection for your Visual, write something like: - * - * \code - * mplot::Visual<> v(width, height, title); - * v.ptype = mplot::perspective_type::orthographic; - * \endcode - */ - void setOrthographic() - { - this->projection = sm::mat::orthographic (this->ortho_lb, this->ortho_rt, this->zNear, this->zFar); - this->invproj = this->projection.inverse(); - } - - // Rotate about the point this->rotation_centre. Subroutine for computeSceneview. - void computeSceneview_about_rotation_centre() - { - sm::mat sv_tr; - sm::mat sv_rot; - sv_tr.translate (this->scenetrans_delta); - // A rotation delta in world frame about the 'screen centre' - sv_rot.translate (this->rotation_centre); - sv_rot.rotate (this->rotation_delta); - sv_rot.translate (-this->rotation_centre); - - this->sceneview = sv_tr * sv_rot * this->savedSceneview; - this->sceneview_tr = sv_tr * this->savedSceneview_tr; - } - - // Get a camera movement that moves us nearer to target. - template - sm::vec get_cam_movement (sm::mat& current, const sm::mat& target, - sm::vec& vel, const T tc) const - { - const sm::vec delta = target.translation() - current.translation(); - const sm::vec force = delta - (vel * T{2}); - sm::vec pos_shift = vel * tc; - vel += force * tc; - return pos_shift; - } - - template - sm::quaternion get_cam_rotation (const sm::quaternion& r_cur0, const sm::mat& target, - T& rvel, const T tc) const - { - sm::mat target0 = target; - target0.translate (-target.translation()); - sm::quaternion r_targ0 = target0.rotation(); - r_targ0.renormalize(); - - sm::quaternion r_sz = r_targ0 * r_cur0.inverse(); - sm::vec aa = r_sz.axis_angle(); - T delta = aa[3]; // The angle subtended by the rotation - T force = delta - (rvel * T{2}); - // rvel is radpersec delta/tc - T prop = rvel * tc; - rvel += force * tc; - sm::quaternion newpos = r_cur0.slerp (r_targ0, prop); - return newpos; // rather than prop, as in get_cam_movement - } - - // Compile-time function to create a rotate-about-y transform - static constexpr sm::mat rotate_about_y() - { - sm::mat r; - r.rotate (sm::vec<>::uy(), sm::mathconst::pi); - return r; - } - - // Hold an offset translation and rotation for the follow-me camera - static constexpr sm::vec folcam_offset_tr_default = {0, 0.01f, -0.06f}; - sm::vec folcam_offset_tr = folcam_offset_tr_default; - sm::quaternion folcam_offset_rot; - - sm::mat update_folcam_viewmatrix() - { - sm::mat fol_cur; - - if (this->followedVM == nullptr) { return fol_cur; } - - // Target view from the followedVM - //sm::mat fol_targ = this->followedVM->getViewMatrix() * this->folcam_offset; - sm::mat rmat; - rmat.rotate (folcam_offset_rot); - sm::mat fol_targ = this->followedVM->getViewMatrix() * rmat; - fol_targ.translate (folcam_offset_tr); - - // Compute folcam_viewmatrix from sceneview (it's the inverse, along with a rotation) - constexpr sm::mat rotn_y = rotate_about_y(); - sm::mat folcam_viewmatrix = this->sceneview.inverse() * rotn_y; - - const sm::vec folcam_vm_trans = folcam_viewmatrix.translation(); - - fol_cur.translate (folcam_vm_trans); // encode just the location of the following camera - - // The current rotation of the scene view - folcam_viewmatrix.translate (-folcam_vm_trans); - sm::quaternion r_cur0 = folcam_viewmatrix.rotation(); - r_cur0.renormalize(); - - // get_cam_movement computes the positional shift - sm::vec pos_shift = this->get_cam_movement (fol_cur, fol_targ, - this->followedVM_vel, this->trans_tc); - // get_cam_rotation computes the rotation for the next camera position - sm::quaternion cam_rotn = this->get_cam_rotation (r_cur0, fol_targ, - this->followedVM_rvel, this->rotn_tc); - - // set the translation/rotation into fol_cur - fol_cur.pretranslate (pos_shift); - fol_cur.rotate (cam_rotn); - - // Distance to rotation centre should be the distance to the followedVM - this->d_to_rotation_centre = folcam_offset_tr.length(); - - // fol_cur now contains the new position and orientation for the following camera - return fol_cur; - } - - // A follow-me camera view - void computeSceneview_for_follower() - { - sm::mat folcam_viewmatrix = this->update_folcam_viewmatrix(); - constexpr sm::mat rotn_y = rotate_about_y(); - this->sceneview = rotn_y * folcam_viewmatrix.inverse(); - this->savedSceneview = this->sceneview; - } - - // This is called every time render() is called - void computeSceneview() - { - if (this->options.test (visual_options::viewFollowsVMBehind) && this->followedVM != nullptr) { - // Use scenetrans_delta to shift the view with the scrollwheel - this->folcam_offset_tr += this->scenetrans_delta; - this->scenetrans_delta.zero(); - if (this->state.test (visual_state::scrolling)) { this->state.reset (visual_state::scrolling); } - this->computeSceneview_for_follower(); - return; - } - - if (std::abs(this->scenetrans_delta.sum()) > 0.0f || this->rotation_delta.is_zero_rotation() == false) { - // Calculate model view transformation - transforming from "model space" to "worldspace". - //std::cout << "standard view, call computeSceneview_about_rotation_centre\n"; - this->computeSceneview_about_rotation_centre(); - } // else don't change sceneview - //else { std::cout << "No changing sceneview...\n"; } - - //std::cout << "sceneview\n" << sceneview << std::endl; - - if (this->state.test (visual_state::scrolling)) { - this->scenetrans_delta.zero(); - this->state.reset (visual_state::scrolling); - } - - if (this->options.test (visual_options::viewFollowsVMTranslations) - && this->followedVM != nullptr - && this->followedLastViewMatrix != this->followedVM->getViewMatrix()) { // NEED KNOWLEDGE OF VISUALMODEL - - // Move camera the difference between followedLastViewMatrix and - // followedVM->getViewMatrix() in the screen frame of reference. - sm::vec fol_screenframe = (this->sceneview * followedLastViewMatrix.translation() - - this->sceneview * followedVM->getViewMatrix().translation()).less_one_dim(); - - this->sceneview.pretranslate (fol_screenframe); - this->sceneview_tr.pretranslate (fol_screenframe); - this->savedSceneview.pretranslate (fol_screenframe); - this->savedSceneview_tr.pretranslate (fol_screenframe); - - this->followedLastViewMatrix = this->followedVM->getViewMatrix(); // NEED KNOWLEDGE OF VISUALMODEL - } - } - - //! A vector of pointers to all the mplot::VisualModels (HexGridVisual, - //! ScatterVisual, etc) which are going to be rendered in the scene. - std::vector>> vm; - - //! If the view should follow a model (options viewFollowsVMTranslations and ...Rotations), this is the one. - mplot::VisualModel* followedVM = nullptr; - - //! Holds the current velocy of the followedVM follower - sm::vec followedVM_vel = {}; - //! Current rotational speed (how fast we slerp) - float followedVM_rvel = 0.0f; - - //! Holds the viewmatrix of the followedVM the last time we called render - sm::mat followedLastViewMatrix; - - // Initialize OpenGL shaders, set some flags (Alpha, Anti-aliasing), read in any external - // state from json, and set up the coordinate arrows and any VisualTextModels that will be - // required to render the Visual. - virtual void init_gl() = 0; - - // Read-from-json code that is called from init_gl in all implementations: - void read_scenetrans_from_json() - { - // If possible, read in scenetrans and rotation state from a special config file - try { - nlohmann::json vconf; - std::ifstream fi; - fi.open ("/tmp/Visual.json", std::ios::in); - fi >> vconf; - this->scenetrans_default[0] = vconf.contains("scenetrans_x") ? vconf["scenetrans_x"].get() : this->scenetrans_default[0]; - this->scenetrans_default[1] = vconf.contains("scenetrans_y") ? vconf["scenetrans_y"].get() : this->scenetrans_default[1]; - this->scenetrans_default[2] = vconf.contains("scenetrans_z") ? vconf["scenetrans_z"].get() : this->scenetrans_default[2]; - - this->rotation_default.w = vconf.contains("scenerotn_w") ? vconf["scenerotn_w"].get() : this->rotation_default.w; - this->rotation_default.x = vconf.contains("scenerotn_x") ? vconf["scenerotn_x"].get() : this->rotation_default.x; - this->rotation_default.y = vconf.contains("scenerotn_y") ? vconf["scenerotn_y"].get() : this->rotation_default.y; - this->rotation_default.z = vconf.contains("scenerotn_z") ? vconf["scenerotn_z"].get() : this->rotation_default.z; - - this->sceneview.set_identity(); - this->sceneview.translate (this->scenetrans_default); - this->sceneview.rotate (this->rotation_default); - this->sceneview_tr.set_identity(); - this->sceneview_tr.translate (this->scenetrans_default); - this->scenetrans_delta.zero(); - this->rotation_delta.reset(); - - } catch (...) { - // No problem if we couldn't read /tmp/Visual.json - } - } - - //! The window (and OpenGL context) for this Visual - mplot::win_t* window = nullptr; - - //! Each window has an ID number, which is passed to the owned VisualModels - uint32_t visual_id = std::numeric_limits::max(); - - //! Current window width - int window_w = 640; - //! Current window height - int window_h = 480; - - //! The title for the Visual. Used in window title and if saving out 3D model or png image. - std::string title = "mathplot"; - - //! The user's 'selected visual model'. For model specific changes to alpha and possibly colour - unsigned int selectedVisualModel = 0u; - - //! A little model of the coordinate axes. - std::unique_ptr> coordArrows; - - //! Position coordinate arrows on screen. Configurable at mplot::Visual construction. - sm::vec coordArrowsOffset = { -0.8f, -0.8f }; - - /* - * Variables to manage projection and rotation of the scene - */ - - //! Current cursor position - sm::vec cursorpos = {}; - - //! The default z position for VisualModels should be 'away from the screen' (negative) so we can see them! - constexpr static float zDefault = -5.0f; - - //! A delta scene translations - sm::vec scenetrans_delta = {}; - - //! Default for scene translation. This is a scene position that can be reverted to, to - //! 'reset the view'. This is copied into sceneview when user presses Ctrl-a. - sm::vec scenetrans_default = { 0.0f, 0.0f, zDefault }; - - //! The world depth at which text objects should be rendered - float text_z = -1.0f; - - //! Screen coordinates of the position of the last mouse press - sm::vec mousePressPosition = {}; - - //! Add additional rotation to the scene - sm::quaternion rotation_delta; - - //! The default rotation of the scene, to reconstruct the default sceneview matrix/reset rotation. - sm::quaternion rotation_default; - - //! A coordinate in the scene about which to perform a mouse-driven rotation. May be set to - //! the centre of the closest VisualModel object. - sm::vec rotation_centre = {}; - - // Distance to the 'rotation centre'. Used to scale the effect of the scroll wheel - float d_to_rotation_centre = -zDefault; - - //! The projection matrix is a member of this class. Value is set during setPerspective() or setOrthographic() - sm::mat projection; - - //! The inverse of the projection. Value is set during setPerspective() or setOrthographic() - sm::mat invproj; - - //! The sceneview matrix, which changes as the user moves the view with mouse - //! movements. Initialized in VisualOwnable constructor. - sm::mat sceneview; - - //! The non-rotating sceneview matrix, updated only from mouse translations (avoiding rotations) - sm::mat sceneview_tr; - - //! Saved sceneview at mouse button down - sm::mat savedSceneview; - - //! Saved sceneview_tr - sm::mat savedSceneview_tr; - - public: - - //! Getter for d_to_rotation_centre - float get_d_to_rotation_centre() const { return this->d_to_rotation_centre; } - - /* - * Generic callback handlers - */ - - using keyaction = mplot::keyaction; - using keymod = mplot::keymod; - using key = mplot::key; - // The key_callback handler uses GLFW codes, but they're in a mplot header (keys.h) - template - bool key_callback (int _key, int scancode, int action, int mods) // can't be virtual. - { - bool needs_render = false; - - if constexpr (owned == true) { // If Visual is 'owned' then the owning system deals with program exit - // Exit action - if (_key == key::q && (mods & keymod::control) && action == keyaction::press) { - this->signal_to_quit(); - } - } - - if (this->state.test (visual_state::sceneLocked) == false - && _key == key::c && (mods & keymod::control) && action == keyaction::press) { - this->options.flip (visual_options::showCoordArrows); - needs_render = true; - } - - if (_key == key::h && (mods & keymod::control) && action == keyaction::press) { - // Help to stdout: - std::cout << "Ctrl-h: Output this help to stdout\n" - << "Mouse-primary: rotate mode (use Ctrl to change axis)\n" - << "Mouse-secondary: translate mode\n"; - if constexpr (owned == true) { // If Visual is 'owned' then the owning system deals with program exit - std::cout << "Ctrl-q: Request exit\n"; - } - std::cout << "Ctrl-v: Un-pause\n" - << "Ctrl-l: Toggle the scene lock\n" - << "Ctrl-c: Toggle coordinate arrows\n" - << "Ctrl-s: Take a snapshot\n" - << "Ctrl-m: Save 3D models in .gltf format (open in e.g. blender)\n" - << "Ctrl-a: Reset default view\n" - << "Ctrl-o: Reduce field of view\n" - << "Ctrl-p: Increase field of view\n" - << "Ctrl-y: Cycle perspective\n" - << "Ctrl-k: Toggle rotate about central model or scene origin\n" - << "Ctrl-b: Toggle between 'rotate about vertical', or 'mathplot tilt'\n" - << "Ctrl-d: Switch the vertical axis used in 'rotate about vertical' mode\n" - << "Ctrl-z: Show the current scenetrans/rotation and save to /tmp/Visual.json\n" - << "Ctrl-u: Reduce zNear cutoff plane\n" - << "Ctrl-i: Increase zNear cutoff plane\n" - << "Ctrl-j: Toggle bounding boxes\n" - << "Ctrl-Shift-s: Output shaders to stdout\n" - << "F1-F10: Select model index (with shift: toggle hide)\n" - << "Shift-Left: Decrease opacity of selected model\n" - << "Shift-Right: Increase opacity of selected model\n" - << std::flush; - } - - if (_key == key::l && (mods & keymod::control) && action == keyaction::press) { - this->state.flip (visual_state::sceneLocked); - std::cout << "Scene is now " << (this->state.test (visual_state::sceneLocked) ? "" : "un-") << "locked\n"; - } - - if (_key == key::v && (mods & keymod::control) && action == keyaction::press) { - if (this->state.test (visual_state::paused)) { - this->state.set (visual_state::paused, false); - std::cout << "Scene un-paused\n"; - } // else no-op - } - - if (_key == key::s && (mods & (keymod::control | keymod::shift)) && action == keyaction::press) { - - if ((mods & (keymod::control | keymod::shift)) == (keymod::control | keymod::shift)) { - // Ctrl-Shift-s gives you the default shaders - std::cout << "The built-in shader programs are:\n"; - std::cout << "\nVisual.vert.glsl\n" - << "----------------\n" - << mplot::getDefaultVtxShader(glver) << std::endl; - std::cout << "\nVisual.frag.glsl\n" - << "----------------\n" - << mplot::getDefaultFragShader(glver) << std::endl; - std::cout << "\nVisText.vert.glsl\n" - << "----------------\n" - << mplot::getDefaultTextVtxShader(glver) << std::endl; - std::cout << "\nVisText.frag.glsl\n" - << "----------------\n" - << mplot::getDefaultTextFragShader(glver) << std::endl; - } else if (mods & keymod::control) { - // Ctrl-s saves a PNG - std::string fname (this->title); - mplot::tools::stripFileSuffix (fname); - fname += ".png"; - // Make fname 'filename safe' - mplot::tools::conditionAsFilename (fname); - this->saveImage (fname); - std::cout << "Saved image to '" << fname << "'\n"; - } - } - - // Save gltf 3D file - if (_key == key::m && (mods & keymod::control) && action == keyaction::press) { - std::string gltffile = this->title; - mplot::tools::stripFileSuffix (gltffile); - gltffile += ".gltf"; - mplot::tools::conditionAsFilename (gltffile); - this->savegltf (gltffile); - std::cout << "Saved 3D file '" << gltffile << "'\n"; - } - - if (_key == key::z && (mods & keymod::control) && action == keyaction::press) { - sm::quaternion rotn = this->sceneview.rotation(); - rotn.renormalize(); - sm::vec scenetrans = this->sceneview.translation(); - std::cout << "Scenetrans setup code:\n v.setSceneTrans (sm::vec{ float{" - << scenetrans.x() << "}, float{" - << scenetrans.y() << "}, float{" - << scenetrans.z() - << "} });" - << "\n v.setSceneRotation (sm::quaternion{ float{" - << rotn.w << "}, float{" << rotn.x << "}, float{" - << rotn.y << "}, float{" << rotn.z << "} });\n"; - std::cout << "Writing scene trans/rotation into /tmp/Visual.json... "; - std::ofstream fout; - fout.open ("/tmp/Visual.json", std::ios::out|std::ios::trunc); - if (fout.is_open()) { - fout << "{\"scenetrans_x\":" << scenetrans.x() - << ", \"scenetrans_y\":" << scenetrans.y() - << ", \"scenetrans_z\":" << scenetrans.z() - << ",\n \"scenerotn_w\":" << rotn.w - << ", \"scenerotn_x\":" << rotn.x - << ", \"scenerotn_y\":" << rotn.y - << ", \"scenerotn_z\":" << rotn.z << "}\n"; - fout.close(); - std::cout << "Success.\n"; - } else { - std::cout << "Failed.\n"; - } - } - - // Set selected model - if (_key == key::f1 && action == keyaction::press) { - this->selectedVisualModel = 0; - std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; - } else if (_key == key::f2 && action == keyaction::press) { - if (this->vm.size() > 1) { this->selectedVisualModel = 1; } - std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; - } else if (_key == key::f3 && action == keyaction::press) { - if (this->vm.size() > 2) { this->selectedVisualModel = 2; } - std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; - } else if (_key == key::f4 && action == keyaction::press) { - if (this->vm.size() > 3) { this->selectedVisualModel = 3; } - std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; - } else if (_key == key::f5 && action == keyaction::press) { - if (this->vm.size() > 4) { this->selectedVisualModel = 4; } - std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; - } else if (_key == key::f6 && action == keyaction::press) { - if (this->vm.size() > 5) { this->selectedVisualModel = 5; } - std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; - } else if (_key == key::f7 && action == keyaction::press) { - if (this->vm.size() > 6) { this->selectedVisualModel = 6; } - std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; - } else if (_key == key::f8 && action == keyaction::press) { - if (this->vm.size() > 7) { this->selectedVisualModel = 7; } - std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; - } else if (_key == key::f9 && action == keyaction::press) { - if (this->vm.size() > 8) { this->selectedVisualModel = 8; } - std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; - } else if (_key == key::f10 && action == keyaction::press) { - if (this->vm.size() > 9) { this->selectedVisualModel = 9; } - std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; - } - - // Toggle hide model if the shift key is down - if ((_key == key::f10 || _key == key::f1 || _key == key::f2 || _key == key::f3 - || _key == key::f4 || _key == key::f5 || _key == key::f6 - || _key == key::f7 || _key == key::f8 || _key == key::f9) - && action == keyaction::press && (mods & keymod::shift)) { - this->vm[this->selectedVisualModel]->toggleHide(); - } - - // Increment/decrement alpha for selected model - if (_key == key::left && (action == keyaction::press || action == keyaction::repeat) && (mods & keymod::shift)) { - if (!this->vm.empty()) { this->vm[this->selectedVisualModel]->decAlpha(); } - } - if (_key == key::right && (action == keyaction::press || action == keyaction::repeat) && (mods & keymod::shift)) { - if (!this->vm.empty()) { this->vm[this->selectedVisualModel]->incAlpha(); } - } - - // Reset view to default - if (this->state.test (visual_state::sceneLocked) == false - && _key == key::a && (mods & keymod::control) && action == keyaction::press) { - std::cout << "Reset to default view\n"; - this->sceneview.set_identity(); - this->sceneview_tr.set_identity(); - this->sceneview.translate (this->scenetrans_default); - this->sceneview.rotate (this->rotation_default); - this->sceneview_tr.translate (this->scenetrans_default); - this->scenetrans_delta.zero(); - this->rotation_delta.reset(); - this->d_to_rotation_centre = -this->scenetrans_default[2]; - //this->folcam_offset = folcam_default(); - this->folcam_offset_tr = folcam_offset_tr_default; - this->folcam_offset_rot.reset(); - needs_render = true; - } - - if (_key == key::k && (action == keyaction::press || action == keyaction::repeat) && (mods & keymod::control)) { - this->options.flip (visual_options::rotateAboutSceneOrigin); - std::cout << "Rotating about " - << (this->options.test (visual_options::rotateAboutSceneOrigin) ? "scene origin" : "central model") - << std::endl; - } - - if (_key == key::j && (action == keyaction::press || action == keyaction::repeat) && (mods & keymod::control)) { - this->options.flip (visual_options::showBoundingBoxes); - // Update all the VisualModels now: - auto vmi = this->vm.begin(); - while (vmi != this->vm.end()) { - (*vmi)->show_bb (this->options.test (visual_options::showBoundingBoxes)); - ++vmi; - } - } - - if (this->state.test (visual_state::sceneLocked) == false - && _key == key::o && (mods & keymod::control) && action == keyaction::press) { - this->fov -= 2; - if (this->fov < 1.0) { this->fov = 2.0; } - std::cout << "FOV reduced to " << this->fov << std::endl; - } - if (this->state.test (visual_state::sceneLocked) == false - && _key == key::p && (mods & keymod::control) && action == keyaction::press) { - this->fov += 2; - if (this->fov > 179.0) { this->fov = 178.0; } - std::cout << "FOV increased to " << this->fov << std::endl; - } - if (this->state.test (visual_state::sceneLocked) == false - && _key == key::u && (mods & keymod::control) && action == keyaction::press) { - this->zNear /= 2; - std::cout << "zNear reduced to " << this->zNear << std::endl; - } - if (this->state.test (visual_state::sceneLocked) == false - && _key == key::i && (mods & keymod::control) && action == keyaction::press) { - this->zNear *= 2; - std::cout << "zNear increased to " << this->zNear << std::endl; - } - if (this->state.test (visual_state::sceneLocked) == false - && _key == key::left_bracket && (mods & keymod::control) && action == keyaction::press) { - this->zFar /= 2; - std::cout << "zFar reduced to " << this->zFar << std::endl; - } - if (this->state.test (visual_state::sceneLocked) == false - && _key == key::right_bracket && (mods & keymod::control) && action == keyaction::press) { - this->zFar *= 2; - std::cout << "zFar increased to " << this->zFar << std::endl; - } - - if (_key == key::y && (mods & keymod::control) && action == keyaction::press) { - if (this->ptype == mplot::perspective_type::perspective) { - this->ptype = mplot::perspective_type::orthographic; - } else if (this->ptype == mplot::perspective_type::orthographic) { - this->ptype = mplot::perspective_type::perspective; - } - needs_render = true; - } - - if (_key == key::d && (mods & keymod::control) && action == keyaction::press) { - this->switch_scene_vertical_axis(); - } - - if (_key == key::b && (mods & keymod::control) && action == keyaction::press) { - this->options.flip (visual_options::rotateAboutVertical); - if (this->options.test (visual_options::rotateAboutVertical)) { - std::cout << "Mouse rotates scene about vertical axis\n"; - } else { - std::cout << "Mouse tilts scene as in the original mathplot\n"; - } - } - - this->key_callback_extra (_key, scancode, action, mods); - - return needs_render; - } - - // Switch between 'z' up and 'y' up - void switch_scene_vertical_axis() - { - if (this->scene_up == sm::vec<>::uy()) { - std::cout << "Changing 'scene up' to uz\n"; - this->scene_up = sm::vec<>::uz(); - this->scene_right = sm::vec<>::ux(); - this->scene_out = -sm::vec<>::uy(); - } else if (this->scene_up == sm::vec<>::uz()) { - std::cout << "Changing 'scene up' to uy\n"; - this->scene_up = sm::vec<>::uy(); - this->scene_right = sm::vec<>::ux(); - this->scene_out = sm::vec<>::uz(); - } else { - std::cout << "Not changing user-specified 'scene up' from " << this->scene_up << "\n"; - } - } - - //! Rotate the scene about axis by angle (angle in radians) - void rotate_scene (const sm::vec& axis, const float angle) - { - sm::quaternion rotnQuat (axis, -angle); - this->sceneview.rotate (rotnQuat); - } - - //! Find the rotation centre; either the scene origin or the centre of a perceptually nearby VM - void find_rotation_centre() - { - // When rotating about scene origin, find translation of scene centre from screen centre - if (this->options.test (visual_options::rotateAboutSceneOrigin) == true) { - this->rotation_centre = this->savedSceneview.translation(); - return; - } - - // Otherwise, find the centre of a visual model to rotate about - constexpr sm::vec v1 = { 0.0f, 0.0f, -100.0f }; - constexpr sm::vec v2 = { 0.0f, 0.0f, 100.0f }; - constexpr sm::vec v2v1 = v1 - v2; - - // A rotation delta in world frame about the 'screen centre'. This is a default: - if (this->rotation_centre == sm::vec{}) { - this->rotation_centre = { 0.0f, 0.0f, this->savedSceneview.translation().z() + this->scenetrans_delta.z() }; - } - - // There's an option to write out the bounding box corners to a file that can be - // displayed with debug_boundingboxes.cpp - std::ofstream fout; - uint32_t ci = 0; - if (options.test (visual_options::boundingBoxesToJson)) { - fout.open ("/tmp/mathplot_bounding_boxes.json", std::ios::out | std::ios::trunc); - if (fout.is_open()) { fout << "{\n"; } - } - - std::multimap, mplot::VisualModel*> > possible_centres; - auto vmi = this->vm.begin(); - while (vmi != this->vm.end()) { - - // vm_bools comes from VisualModel and would need to be shared - if ((*vmi)->flags.test (mplot::vm_bools::compute_bb) && !(*vmi)->flags.test (mplot::vm_bools::twodimensional)) { - - sm::vec tr_bb_centre = (this->savedSceneview * (*vmi)->get_viewmatrix_bb_centre()).less_one_dim(); - - if (options.test (visual_options::boundingBoxesToJson) && fout.is_open()) { - sm::range> modelbb = (*vmi)->bb; // Get the VisualModel bounding box - modelbb -= (*vmi)->bb.mid(); // centre the bounding box about (VM frame's) origin - modelbb += tr_bb_centre; - fout << " \"b" << (ci + 1) << "\": [" << modelbb.min.str_comma_separated() << "],\n"; - fout << " \"b" << (ci + 2) << "\": [" << modelbb.max.str_comma_separated() << "],\n"; - ci += 2; - } - - // Highlight central VM in any case. Really, want to highlight the selected possible centre. - if (options.test (visual_options::highlightRotationVM)) { (*vmi)->show_bb (false); } - - // Find perpendicular distance from line to point pc - sm::vec cv = tr_bb_centre - v1; - float pdist = cv.length() * std::sin (v2v1.angle (cv)); - - if (tr_bb_centre[2] < 0.0f) { // Only if in front of viewer (z must be negative) - // Perp. distance as key, value is tuple of BB centre and visualmodel pointer - possible_centres.insert ({ pdist, { tr_bb_centre, (*vmi).get() } }); - } - } - ++vmi; - } - - if (options.test (visual_options::boundingBoxesToJson) && fout.is_open()) { - fout << " \"n\": " << ci << "\n}\n"; - fout.close(); - } - - if (!possible_centres.empty()) { - const auto [rcentre, vmptr] = possible_centres.begin()->second; - this->rotation_centre = rcentre; - this->d_to_rotation_centre = this->rotation_centre.length(); - if (options.test (visual_options::highlightRotationVM)) { vmptr->show_bb (true); } - } // else don't change rotation_centre - } - - virtual bool cursor_position_callback (double x, double y) - { - this->cursorpos[0] = static_cast(x); - this->cursorpos[1] = static_cast(y); - - sm::vec mouseMoveWorld = { 0.0f, 0.0f, 0.0f }; - - bool needs_render = false; - - // Mouse-movement gain - constexpr float mm_gain = 160.0f; - - // This is "rotate the scene" (and not "rotate one VisualModel") - if (this->state.test (visual_state::rotateMode)) { - // Convert mousepress/cursor positions (in pixels) to the range -1 -> 1: - sm::vec p0_coord = this->mousePressPosition; - p0_coord -= this->window_w * 0.5f; - p0_coord /= this->window_w * 0.5f; - sm::vec p1_coord = this->cursorpos; - p1_coord -= this->window_w * 0.5f; - p1_coord /= this->window_w * 0.5f; - // Note: don't update this->mousePressPosition until user releases button. - - // Add the depth at which the object lies. Use forward projection to determine the - // correct z coordinate for the inverse projection. This assumes only one object. - sm::vec point = { 0.0f, 0.0f, this->savedSceneview.translation().z(), 1.0f }; - sm::vec pp = this->projection * point; - float coord_z = pp[2] / pp[3]; // divide by pp[3] is divide by/normalise by 'w'. - - // p0_coord/p1_coord in range -1 to 1, with a z value of 1. - sm::vec p0 = { p0_coord[0], p0_coord[1], coord_z, 1.0f }; - sm::vec p1 = { p1_coord[0], p1_coord[1], coord_z, 1.0f }; - - // Apply the inverse projection to get two points in the world frame of reference - // for the mouse movement - sm::vec v0 = this->invproj * p0; - sm::vec v1 = this->invproj * p1; - - /* - * This computes the difference between v0 and v1, the 2 mouse positions in the - * world space. Note the swap between x and y. mouseMoveWorld is used as the - * rotation axis in the viewer's frame of reference or its values are used to set - * rotations about scene axes (if rotateAboutVertical is true) - */ - if (this->state.test (visual_state::rotateModMode)) { - // Sort of "rotate the page" mode. - mouseMoveWorld[2] = (-(v1[1] - v0[1]) + (v1[0] - v0[0])); - } else { - mouseMoveWorld[1] = -(v1[0] - v0[0]); - mouseMoveWorld[0] = -(v1[1] - v0[1]); - } - mouseMoveWorld *= mm_gain; - - if (this->options.test (visual_options::rotateAboutVertical) == true - && this->options.test (visual_options::viewFollowsVMBehind) == false) { - - if (this->state.test (visual_state::rotateModMode)) { - // What to do about rotate mod mode in this rotation scheme? Rotate about the missing axis for now. - this->rotation_delta.set_rotation (this->scene_out, mouseMoveWorld[2] * -sm::mathconst::deg2rad); - } else { - // For now, rotate about the scene up axis - sm::vec<> mod_up = this->savedSceneview.rotation() * this->scene_up; - sm::quaternion r1 (mod_up, mouseMoveWorld[1] * -sm::mathconst::deg2rad); - sm::quaternion r2 (this->scene_right, mouseMoveWorld[0] * -sm::mathconst::deg2rad); - this->rotation_delta = r2 * r1; - } - } else if (this->options.test (visual_options::viewFollowsVMBehind) == true) { - //std::cout << "\nmouseMoveWorld[0]: " << mouseMoveWorld[0] << std::endl; // pitch - //std::cout << "mouseMoveWorld[1]: " << mouseMoveWorld[1] << std::endl; // about +- 40ish. leftright yaw - float pitch = mouseMoveWorld[0]; - float yaw = mouseMoveWorld[1]; - pitch = pitch > 10.0f ? 10.0f : pitch; - pitch = pitch < -65.0f ? -65.0f : pitch; // negative pitch is 'looking down' on the agent - yaw = yaw > 45.0f ? 45.0f : yaw; - yaw = yaw < -45.0f ? -45.0f : yaw; - - sm::quaternion r1 (this->scene_up, yaw * sm::mathconst::deg2rad); - sm::quaternion r2 (this->scene_right, pitch * -sm::mathconst::deg2rad); - this->folcam_offset_rot = r2 * r1; - - } else { - // rotation_delta is the mouse-commanded rotation in the scene frame of reference - this->rotation_delta.set_rotation (mouseMoveWorld, mouseMoveWorld.length() * -sm::mathconst::deg2rad); - } - - needs_render = true; - - } else if (this->state.test (visual_state::translateMode)) { // allow only rotate OR translate for a single mouse movement - // Convert mousepress/cursor positions (in pixels) to the range -1 -> 1: - sm::vec p0_coord = this->mousePressPosition; - p0_coord -= this->window_w * 0.5f; - p0_coord /= this->window_w * 0.5f; - sm::vec p1_coord = this->cursorpos; - p1_coord -= this->window_w * 0.5f; - p1_coord /= this->window_w * 0.5f; - - this->mousePressPosition = this->cursorpos; - - // Add the depth at which the object lies. Use forward projection to determine the - // correct z coordinate for the inverse projection. This assumes only one object. - sm::vec point = { 0.0f, 0.0f, -this->d_to_rotation_centre, 1.0f }; - sm::vec pp = this->projection * point; - float coord_z = pp[2] / pp[3]; // divide by pp[3] is divide by/normalise by 'w'. - - // Construct two points for the start and end of the mouse movement - sm::vec p0 = { p0_coord[0], p0_coord[1], coord_z, 1.0f }; - sm::vec p1 = { p1_coord[0], p1_coord[1], coord_z, 1.0f }; - // Apply the inverse projection to get two points in the world frame of reference: - sm::vec v0 = this->invproj * p0; - sm::vec v1 = this->invproj * p1; - // This computes the difference betwen v0 and v1, the 2 mouse positions in the world - mouseMoveWorld[0] = (v1[0] / v1[3]) - (v0[0] / v0[3]); - mouseMoveWorld[1] = (v1[1] / v1[3]) - (v0[1] / v0[3]); - // Note: mouseMoveWorld[2] is unmodified - - // We "translate the whole scene" - used by 2D projection shaders - this->scenetrans_delta[0] += mouseMoveWorld[0]; - - if (this->options.test (visual_options::viewFollowsVMBehind) == true) { - this->scenetrans_delta[1] += mouseMoveWorld[1]; // opp. sense in follow-me - } else { - this->scenetrans_delta[1] -= mouseMoveWorld[1]; - } - - needs_render = true; // updates viewproj; uses this->scenetrans - } - - return needs_render; - } - - virtual void mouse_button_callback (int button, int action, int mods = 0) - { - // If the scene is locked, then ignore the mouse movements - if (this->state.test (visual_state::sceneLocked)) { return; } - - // Record the position and rotation at which the button was pressed - if (action == keyaction::press) { // Button down - this->mousePressPosition = this->cursorpos; - this->savedSceneview = this->sceneview; - this->savedSceneview_tr = this->sceneview_tr; - this->scenetrans_delta.zero(); - this->rotation_delta.reset(); - } else if (action == keyaction::release) { - // On mouse button release, zero the deltas: - this->scenetrans_delta.zero(); - this->rotation_delta.reset(); - } - - this->find_rotation_centre(); - - if (button == mplot::mousebutton::left) { // Primary button means rotate - if (action == keyaction::press) { - this->state.set (visual_state::mouseButtonLeftPressed); - } else if (action == keyaction::release) { - this->state.set (visual_state::mouseButtonLeftPressed, false); - } - this->state.set (visual_state::rotateModMode, ((mods & keymod::control) ? true : false)); - this->state.set (visual_state::rotateMode, (action == keyaction::press)); - this->state.set (visual_state::translateMode, false); - } else if (button == mplot::mousebutton::right) { // Secondary button means translate - if (action == keyaction::press) { - this->state.set (visual_state::mouseButtonRightPressed); - } else if (action == keyaction::release) { - this->state.set (visual_state::mouseButtonRightPressed, false); - } - this->state.set (visual_state::rotateMode, false); - this->state.set (visual_state::translateMode, (action == keyaction::press)); - } - - this->mouse_button_callback_extra (button, action, mods); - } - - virtual bool window_size_callback (int width, int height) - { - this->window_w = width; - this->window_h = height; - return true; // needs_render - } - - virtual void window_close_callback() - { - if (this->options.test (visual_options::preventWindowCloseWithButton) == false) { - this->signal_to_quit(); - } else { - std::cerr << "Ignoring user request to exit (Visual::preventWindowCloseWithButton)\n"; - } - } - - //! When user scrolls, we translate the scene - virtual bool scroll_callback (double xoffset, double yoffset) - { - // yoffset non-zero indicates that the most common scroll wheel is changing. If there's - // a second scroll wheel, xoffset will be passed non-zero. They'll be 0 or +/- 1. - - if (this->state.test (visual_state::sceneLocked)) { return false; } - - this->savedSceneview = this->sceneview; - this->savedSceneview_tr = this->sceneview_tr; - this->scenetrans_delta.zero(); - this->rotation_delta.reset(); - this->state.set (visual_state::scrolling); - - if (this->ptype == perspective_type::orthographic) { - // In orthographic, the wheel should scale ortho_lb and ortho_rt - sm::vec _lb = this->ortho_lb + (yoffset * this->scenetrans_stepsize); - sm::vec _rt = this->ortho_rt - (yoffset * this->scenetrans_stepsize); - if (_lb < 0.0f && _rt > 0.0f) { - this->ortho_lb = _lb; - this->ortho_rt = _rt; - } - - } else { // perspective_type::perspective - - // xoffset does what mouse drag left/right in rotateModMode does (L/R scene trans) - this->scenetrans_delta[0] -= xoffset * this->scenetrans_stepsize; - - // yoffset does the 'in-out zooming' - - // How to make scenetrans_stepsize adaptive to the scale of the environment and change when close to objects? - float y_step = static_cast(yoffset) * this->scenetrans_stepsize * this->d_to_rotation_centre; - sm::vec scroll_move_y = { 0.0f, y_step, 0.0f, 1.0f }; - - this->scenetrans_delta[2] += scroll_move_y[1]; - - if (this->d_to_rotation_centre > (this->zFar / 2.0f) && scroll_move_y[1] < 0.0f) { - // Cancel movement - this->scenetrans_delta[2] = 0.0f; - scroll_move_y[1] = 0.0f; - } - - this->d_to_rotation_centre -= this->scenetrans_delta[2]; - } - return true; // needs_render - } - - //! Extra key callback handling, making it easy for client programs to implement their own actions - virtual void key_callback_extra ([[maybe_unused]] int key, [[maybe_unused]] int scancode, - [[maybe_unused]] int action, [[maybe_unused]] int mods) {} - - //! Extra mousebutton callback handling, making it easy for client programs to implement their own actions - virtual void mouse_button_callback_extra ([[maybe_unused]] int button, [[maybe_unused]] int action, - [[maybe_unused]] int mods) {} - - //! A callback that client code can set so that it knows when user has signalled to - //! mplot::Visual that it's quit time. - std::function external_quit_callback; - - protected: - //! This internal quit function sets a 'readyToFinish' flag that your code can respond to, - //! and calls an external callback function that you may have set up. - void signal_to_quit() - { - if (this->options.test (visual_options::userInfoStdout)) { std::cout << "User requested exit.\n"; } - // 1. Set our 'readyToFinish' flag to true - this->state.set (visual_state::readyToFinish); - // 2. Call any external callback that's been set by client code - if (this->external_quit_callback) { this->external_quit_callback(); } - } - - //! Unpause, allowing pauseOpen() to return - void unpause() { this->state.reset (visual_state::paused); } - }; - -} // namespace mplot diff --git a/mplot/VisualFace.h b/mplot/VisualFace.h index bce71c67..4e6ef68b 100644 --- a/mplot/VisualFace.h +++ b/mplot/VisualFace.h @@ -1,11 +1,10 @@ /*! * \file * - * Declares a VisualFace class to hold the information about a (Freetype-managed) font face and the - * GL-textures that will reproduce it. + * Declares a VisualFace class to hold the information about a (Freetype-managed) font + * face and the GL-textures that will reproduce it. * - * This class is derived from VisualFaceBase and adds multi-context-safe GLAD-arranged GL function - * calls. + * This is the non-GL base class. * * \author Seb James * \date November 2020 @@ -24,19 +23,165 @@ module; #include #include FT_FREETYPE_H +#include #include +#include +#include -export module mplot.core:visualface; +#include + +/* + * The following inline assembly incorporates Vera.ttf and friends *into the binary*. We + * have different code for Linux and Mac. Both tested only on Intel CPUs. + */ + +#ifdef __linux__ + +# ifdef __aarch64__ + +// "a", @progbits isn't liked by pi/arm, but "a", %progbits DOES seem to be necessary +asm("\n.pushsection vera_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/Vera.ttf\"\n.popsection\n"); +asm("\n.pushsection verait_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraIt.ttf\"\n.popsection\n"); +asm("\n.pushsection verabd_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBd.ttf\"\n.popsection\n"); +asm("\n.pushsection verabi_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBI.ttf\"\n.popsection\n"); +asm("\n.pushsection veramono_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMono.ttf\"\n.popsection\n"); +asm("\n.pushsection veramoit_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoIt.ttf\"\n.popsection\n"); +asm("\n.pushsection veramobd_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBd.ttf\"\n.popsection\n"); +asm("\n.pushsection veramobi_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBI.ttf\"\n.popsection\n"); +asm("\n.pushsection verase_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSe.ttf\"\n.popsection\n"); +asm("\n.pushsection verasebd_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSeBd.ttf\"\n.popsection\n"); + +// DejaVu Sans allows for Greek symbols and will be the default +asm("\n.pushsection dvsans_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans.ttf\"\n.popsection\n"); +asm("\n.pushsection dvsansit_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Oblique.ttf\"\n.popsection\n"); +asm("\n.pushsection dvsansbd_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Bold.ttf\"\n.popsection\n"); +asm("\n.pushsection dvsansbi_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-BoldOblique.ttf\"\n.popsection\n"); + +# else + +// "a", @progbits means 'allocatable section containing type data'. It seems not to be strictly necessary. +asm("\n.pushsection vera_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/Vera.ttf\"\n.popsection\n"); +asm("\n.pushsection verait_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraIt.ttf\"\n.popsection\n"); +asm("\n.pushsection verabd_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBd.ttf\"\n.popsection\n"); +asm("\n.pushsection verabi_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBI.ttf\"\n.popsection\n"); +asm("\n.pushsection veramono_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMono.ttf\"\n.popsection\n"); +asm("\n.pushsection veramoit_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoIt.ttf\"\n.popsection\n"); +asm("\n.pushsection veramobd_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBd.ttf\"\n.popsection\n"); +asm("\n.pushsection veramobi_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBI.ttf\"\n.popsection\n"); +asm("\n.pushsection verase_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSe.ttf\"\n.popsection\n"); +asm("\n.pushsection verasebd_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSeBd.ttf\"\n.popsection\n"); + +// DejaVu Sans allows for Greek symbols and will be the default +asm("\n.pushsection dvsans_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans.ttf\"\n.popsection\n"); +asm("\n.pushsection dvsansit_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Oblique.ttf\"\n.popsection\n"); +asm("\n.pushsection dvsansbd_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Bold.ttf\"\n.popsection\n"); +asm("\n.pushsection dvsansbi_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-BoldOblique.ttf\"\n.popsection\n"); + +#endif + +#elif defined __APPLE__ + +// On Mac, we need a different incantation to use .incbin +asm("\t.global ___start_vera_ttf\n\t.global ___stop_vera_ttf\n___start_vera_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/Vera.ttf\"\n___stop_vera_ttf:\n"); +asm("\t.global ___start_verait_ttf\n\t.global ___stop_verait_ttf\n___start_verait_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraIt.ttf\"\n___stop_verait_ttf:\n"); +asm("\t.global ___start_verabd_ttf\n\t.global ___stop_verabd_ttf\n___start_verabd_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBd.ttf\"\n___stop_verabd_ttf:\n"); +asm("\t.global ___start_verabi_ttf\n\t.global ___stop_verabi_ttf\n___start_verabi_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBI.ttf\"\n___stop_verabi_ttf:\n"); +asm("\t.global ___start_veramono_ttf\n\t.global ___stop_veramono_ttf\n___start_veramono_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMono.ttf\"\n___stop_veramono_ttf:\n"); +asm("\t.global ___start_veramoit_ttf\n\t.global ___stop_veramoit_ttf\n___start_veramoit_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoIt.ttf\"\n___stop_veramoit_ttf:\n"); +asm("\t.global ___start_veramobd_ttf\n\t.global ___stop_veramobd_ttf\n___start_veramobd_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBd.ttf\"\n___stop_veramobd_ttf:\n"); +asm("\t.global ___start_veramobi_ttf\n\t.global ___stop_veramobi_ttf\n___start_veramobi_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBI.ttf\"\n___stop_veramobi_ttf:\n"); +asm("\t.global ___start_verase_ttf\n\t.global ___stop_verase_ttf\n___start_verase_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSe.ttf\"\n___stop_verase_ttf:\n"); +asm("\t.global ___start_verasebd_ttf\n\t.global ___stop_verasebd_ttf\n___start_verasebd_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSeBd.ttf\"\n___stop_verasebd_ttf:\n"); + +asm("\t.global ___start_dvsans_ttf\n\t.global ___stop_dvsans_ttf\n___start_dvsans_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans.ttf\"\n___stop_dvsans_ttf:\n"); +asm("\t.global ___start_dvsansit_ttf\n\t.global ___stop_dvsansit_ttf\n___start_dvsansit_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Oblique.ttf\"\n___stop_dvsansit_ttf:\n"); +asm("\t.global ___start_dvsansbd_ttf\n\t.global ___stop_dvsansbd_ttf\n___start_dvsansbd_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Bold.ttf\"\n___stop_dvsansbd_ttf:\n"); +asm("\t.global ___start_dvsansbi_ttf\n\t.global ___stop_dvsansbi_ttf\n___start_dvsansbi_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-BoldOblique.ttf\"\n___stop_dvsansbi_ttf:\n"); + +#elif defined _MSC_VER + +# include // Includes vera fonts AND DejaVu fonts. +# include + +#elif defined _mplot_WIN__INCBIN // Define this only for parsing this file with the incbin executable to create verafonts.h + +// Visual Studio doesn't allow __asm{} calls in C__ code anymore, so try Dale Weiler's incbin.h +#define INCBIN_PREFIX vf_ +#include +INCBIN(vera, "./fonts/ttf-bitstream-vera/Vera.ttf"); +INCBIN(verait, "./fonts/ttf-bitstream-vera/VeraIt.ttf"); +INCBIN(verabd, "./fonts/ttf-bitstream-vera/VeraBd.ttf"); +INCBIN(verabi, "./fonts/ttf-bitstream-vera/VeraBI.ttf"); +INCBIN(veramono, "./fonts/ttf-bitstream-vera/VeraMono.ttf"); +INCBIN(veramoit, "./fonts/ttf-bitstream-vera/VeraMoIt.ttf"); +INCBIN(veramobd, "./fonts/ttf-bitstream-vera/VeraMoBd.ttf"); +INCBIN(veramobi, "./fonts/ttf-bitstream-vera/VeraMoBI.ttf"); +INCBIN(verase, "./fonts/ttf-bitstream-vera/VeraSe.ttf"); +INCBIN(verasebd, "./fonts/ttf-bitstream-vera/VeraSeBd.ttf"); +// These translation units now have three symbols, eg: +// extern const unsigned char vf_veraData[]; +// extern const unsigned char *const vf_veraEnd; +// extern const unsigned int vf_veraSize; + +INCBIN(dvsans, "./fonts/dejavu/DejaVuSans.ttf"); +INCBIN(dvsansit, "./fonts/dejavu/DejaVuSans-Oblique.ttf"); +INCBIN(dvsansbd, "./fonts/dejavu/DejaVuSans-Bold.ttf"); +INCBIN(dvsansbi, "./fonts/dejavu/DejaVuSans-BoldOblique.ttf"); + +#else +# error "Inline assembly code for including truetype fonts in the binary only work on Linux/MacOS (and then, probably only on Intel compatible compilers. Sorry about that!" +#endif + +// These external pointers are set up by the inline assembly above +#ifndef _MSC_VER +extern const char __start_verabd_ttf[]; +extern const char __stop_verabd_ttf[]; +extern const char __start_verabi_ttf[]; +extern const char __stop_verabi_ttf[]; +extern const char __start_verait_ttf[]; +extern const char __stop_verait_ttf[]; +extern const char __start_veramobd_ttf[]; +extern const char __stop_veramobd_ttf[]; +extern const char __start_veramobi_ttf[]; +extern const char __stop_veramobi_ttf[]; +extern const char __start_veramoit_ttf[]; +extern const char __stop_veramoit_ttf[]; +extern const char __start_veramono_ttf[]; +extern const char __stop_veramono_ttf[]; +extern const char __start_verasebd_ttf[]; +extern const char __stop_verasebd_ttf[]; +extern const char __start_verase_ttf[]; +extern const char __stop_verase_ttf[]; +extern const char __start_vera_ttf[]; +extern const char __stop_vera_ttf[]; + +extern const char __start_dvsans_ttf[]; +extern const char __stop_dvsans_ttf[]; +extern const char __start_dvsansit_ttf[]; +extern const char __stop_dvsansit_ttf[]; +extern const char __start_dvsansbd_ttf[]; +extern const char __stop_dvsansbd_ttf[]; +extern const char __start_dvsansbi_ttf[]; +extern const char __stop_dvsansbi_ttf[]; +#endif + +/* + * Module starts here + */ + +export module mplot.visualface; -import :visualfacebase; -export import :visualfont; import mplot.visualcommon; +import mplot.visualfont; +import mplot.textfeatures; + import sm.vec; -export namespace mplot::visgl +namespace mplot::visgl { - struct VisualFace : public mplot::visgl::VisualFaceBase + struct VisualFace { + VisualFace () {} /*! * Construct with a mplot::VisualFont \a _font, which specifies a supported * font (one which we can legally include in the source code without paying any licence fees, @@ -112,6 +257,248 @@ export namespace mplot::visgl FT_Done_Face (this->face); } - ~VisualFace() {} + ~VisualFace () {} + + //! Set true for informational/debug messages + static constexpr bool debug_visualface = false; + + //! The FT_Face that we're managing + FT_Face face; + + //! The OpenGL character info stuff + std::map glchars; + + protected: + + void init_common (const mplot::VisualFont _font, unsigned int fontpixels, FT_Library& ft_freetype) + { + std::string fontpath = ""; +#ifdef _MSC_VER + char* userprofile = getenv ("USERPROFILE"); + std::string uppath(""); + if (userprofile != nullptr) { + uppath = std::string (userprofile); + } + + switch (_font) { + case VisualFont::DVSans: + { + fontpath = uppath + "\\AppData\\Local\\Temp\\DejaVuSans.ttf"; + this->makeTempFontFile (fontpath, vf_dvsansData, vf_dvsansEnd); + break; + } + case VisualFont::DVSansItalic: + { + fontpath = uppath + "\\AppData\\Local\\Temp\\DejaVuSans-Oblique.ttf"; + this->makeTempFontFile (fontpath, vf_dvsansitData, vf_dvsansitEnd); + break; + } + case VisualFont::DVSansBold: + { + fontpath = uppath + "\\AppData\\Local\\Temp\\DejaVuSans-Bold.ttf"; + this->makeTempFontFile (fontpath, vf_dvsansbdData, vf_dvsansbdEnd); + break; + } + case VisualFont::DVSansBoldItalic: + { + fontpath = uppath + "\\AppData\\Local\\Temp\\DejaVuSans-BoldOblique.ttf"; + this->makeTempFontFile (fontpath, vf_dvsansbiData, vf_dvsansbiEnd); + break; + } + case VisualFont::Vera: + { + fontpath = uppath + "\\AppData\\Local\\Temp\\Vera.ttf"; + this->makeTempFontFile (fontpath, vf_veraData, vf_veraEnd); + break; + } + case VisualFont::VeraItalic: + { + fontpath = uppath + "\\AppData\\Local\\Temp\\VeraIt.ttf"; + this->makeTempFontFile (fontpath, vf_veraitData, vf_veraitEnd); + break; + } + case VisualFont::VeraBold: + { + fontpath = uppath + "\\AppData\\Local\\Temp\\VeraBd.ttf"; + this->makeTempFontFile (fontpath, vf_verabdData, vf_verabdEnd); + break; + } + case VisualFont::VeraBoldItalic: + { + fontpath = uppath + "\\AppData\\Local\\Temp\\VeraBI.ttf"; + this->makeTempFontFile (fontpath, vf_verabiData, vf_verabiEnd); + break; + } + case VisualFont::VeraMono: + { + fontpath = uppath + "\\AppData\\Local\\Temp\\VeraMono.ttf"; + this->makeTempFontFile (fontpath, vf_veramonoData, vf_veramonoEnd); + break; + } + case VisualFont::VeraMonoBold: + { + fontpath = uppath + "\\AppData\\Local\\Temp\\VeraMoBd.ttf"; + this->makeTempFontFile (fontpath, vf_veramobdData, vf_veramobdEnd); + break; + } + case VisualFont::VeraMonoItalic: + { + fontpath = uppath + "\\AppData\\Local\\Temp\\VeraMoIt.ttf"; + this->makeTempFontFile (fontpath, vf_veramoitData, vf_veramoitEnd); + break; + } + case VisualFont::VeraMonoBoldItalic: + { + fontpath = uppath + "\\AppData\\Local\\Temp\\VeraMoBI.ttf"; + this->makeTempFontFile (fontpath, vf_veramobiData, vf_veramobiEnd); + break; + } + case VisualFont::VeraSerif: + { + fontpath = uppath + "\\AppData\\Local\\Temp\\VeraSe.ttf"; + this->makeTempFontFile (fontpath, vf_veraseData, vf_veraseEnd); + break; + } + case VisualFont::VeraSerifBold: + { + fontpath = uppath + "\\AppData\\Local\\Temp\\VeraSeBd.ttf"; + this->makeTempFontFile (fontpath, vf_verasebdData, vf_verasebdEnd); + break; + } + default: + { + std::cout << "ERROR::Unsupported mplot font\n"; + break; + } + } +#else // Non-windows: + switch (_font) { + case VisualFont::DVSans: + { + fontpath = "/tmp/DejaVuSans.ttf"; + this->makeTempFontFile (fontpath, __start_dvsans_ttf, __stop_dvsans_ttf); + break; + } + case VisualFont::DVSansItalic: + { + fontpath = "/tmp/DejaVuSans-Oblique.ttf"; + this->makeTempFontFile (fontpath, __start_dvsansit_ttf, __stop_dvsansit_ttf); + break; + } + case VisualFont::DVSansBold: + { + fontpath = "/tmp/DejaVuSans-Bold.ttf"; + this->makeTempFontFile (fontpath, __start_dvsansbd_ttf, __stop_dvsansbd_ttf); + break; + } + case VisualFont::DVSansBoldItalic: + { + fontpath = "/tmp/DejaVuSans-BoldOblique.ttf"; + this->makeTempFontFile (fontpath, __start_dvsansbi_ttf, __stop_dvsansbi_ttf); + break; + } + case VisualFont::Vera: + { + fontpath = "/tmp/Vera.ttf"; + this->makeTempFontFile (fontpath, __start_vera_ttf, __stop_vera_ttf); + break; + } + case VisualFont::VeraItalic: + { + fontpath = "/tmp/VeraIt.ttf"; + this->makeTempFontFile (fontpath, __start_verait_ttf, __stop_verait_ttf); + break; + } + case VisualFont::VeraBold: + { + fontpath = "/tmp/VeraBd.ttf"; + this->makeTempFontFile (fontpath, __start_verabd_ttf, __stop_verabd_ttf); + break; + } + case VisualFont::VeraBoldItalic: + { + fontpath = "/tmp/VeraBI.ttf"; + this->makeTempFontFile (fontpath, __start_verabi_ttf, __stop_verabi_ttf); + break; + } + case VisualFont::VeraMono: + { + fontpath = "/tmp/VeraMono.ttf"; + this->makeTempFontFile (fontpath, __start_veramono_ttf, __stop_veramono_ttf); + break; + } + case VisualFont::VeraMonoBold: + { + fontpath = "/tmp/VeraMoBd.ttf"; + this->makeTempFontFile (fontpath, __start_veramobd_ttf, __stop_veramobd_ttf); + break; + } + case VisualFont::VeraMonoItalic: + { + fontpath = "/tmp/VeraMoIt.ttf"; + this->makeTempFontFile (fontpath, __start_veramoit_ttf, __stop_veramoit_ttf); + break; + } + case VisualFont::VeraMonoBoldItalic: + { + fontpath = "/tmp/VeraMoBI.ttf"; + this->makeTempFontFile (fontpath, __start_veramobi_ttf, __stop_veramobi_ttf); + break; + } + case VisualFont::VeraSerif: + { + fontpath = "/tmp/VeraSe.ttf"; + this->makeTempFontFile (fontpath, __start_verase_ttf, __stop_verase_ttf); + break; + } + case VisualFont::VeraSerifBold: + { + fontpath = "/tmp/VeraSeBd.ttf"; + this->makeTempFontFile (fontpath, __start_verasebd_ttf, __stop_verasebd_ttf); + break; + } + default: + { + std::cout << "ERROR::Unsupported mplot font\n"; + break; + } + } +#endif // Windows/Non-windows + + // Keep the face as a mplot::Visual owned resource, shared by VisTextModels? + if constexpr (debug_visualface == true) { + std::cout << "FT_New_Face (ft_freetype, " << fontpath << ", 0, &this->face);\n"; + } + if (FT_New_Face (ft_freetype, fontpath.c_str(), 0, &this->face)) { + std::cout << "ERROR::FREETYPE: Failed to load font (font file may be invalid)" << std::endl; + } + + FT_Set_Pixel_Sizes (this->face, 0, fontpixels); + + // Can I check this->face for how many glyphs it has? Yes: + // std::cout << "This face has " << this->face->num_glyphs << " glyphs.\n"; + } + + //! Create a temporary font file at fontpath, using the embedded data + //! starting from filestart and extending to filenend + template + void makeTempFontFile (const std::string& fontpath, T* file_start, T* file_stop) + { + T* p; + if (!mplot::tools::fileExists (fontpath)) { + std::ofstream fout; + fout.open (fontpath.c_str(), std::ios::out | std::ios::trunc | std::ios::binary); + if (fout.is_open()) { + for (p = file_start; p < file_stop; p++) { fout << *p; } + fout.close(); + } else { + std::cout << "WARNING: Failed to open " << fontpath << "!!\n"; + } + } else { + if constexpr (debug_visualface == true) { + std::cout << "INFO: " << fontpath << " already exists, no need to re-create it\n"; + } + } + } }; -} // namespace mplot::visgl +} // namespace diff --git a/mplot/VisualFaceBase.h b/mplot/VisualFaceBase.h deleted file mode 100644 index cad4263a..00000000 --- a/mplot/VisualFaceBase.h +++ /dev/null @@ -1,419 +0,0 @@ -/*! - * \file - * - * Declares a VisualFace class to hold the information about a (Freetype-managed) font - * face and the GL-textures that will reproduce it. - * - * This is the non-GL base class. - * - * \author Seb James - * \date November 2020 - */ -module; - -#include -#include -#include -#include - -#include - -// FreeType for text rendering -#include -#include FT_FREETYPE_H - -/* - * The following inline assembly incorporates Vera.ttf and friends *into the binary*. We - * have different code for Linux and Mac. Both tested only on Intel CPUs. - */ - -#ifdef __linux__ - -# ifdef __aarch64__ - -// "a", @progbits isn't liked by pi/arm, but "a", %progbits DOES seem to be necessary -asm("\n.pushsection vera_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/Vera.ttf\"\n.popsection\n"); -asm("\n.pushsection verait_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraIt.ttf\"\n.popsection\n"); -asm("\n.pushsection verabd_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBd.ttf\"\n.popsection\n"); -asm("\n.pushsection verabi_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBI.ttf\"\n.popsection\n"); -asm("\n.pushsection veramono_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMono.ttf\"\n.popsection\n"); -asm("\n.pushsection veramoit_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoIt.ttf\"\n.popsection\n"); -asm("\n.pushsection veramobd_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBd.ttf\"\n.popsection\n"); -asm("\n.pushsection veramobi_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBI.ttf\"\n.popsection\n"); -asm("\n.pushsection verase_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSe.ttf\"\n.popsection\n"); -asm("\n.pushsection verasebd_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSeBd.ttf\"\n.popsection\n"); - -// DejaVu Sans allows for Greek symbols and will be the default -asm("\n.pushsection dvsans_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans.ttf\"\n.popsection\n"); -asm("\n.pushsection dvsansit_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Oblique.ttf\"\n.popsection\n"); -asm("\n.pushsection dvsansbd_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Bold.ttf\"\n.popsection\n"); -asm("\n.pushsection dvsansbi_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-BoldOblique.ttf\"\n.popsection\n"); - -# else - -// "a", @progbits means 'allocatable section containing type data'. It seems not to be strictly necessary. -asm("\n.pushsection vera_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/Vera.ttf\"\n.popsection\n"); -asm("\n.pushsection verait_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraIt.ttf\"\n.popsection\n"); -asm("\n.pushsection verabd_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBd.ttf\"\n.popsection\n"); -asm("\n.pushsection verabi_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBI.ttf\"\n.popsection\n"); -asm("\n.pushsection veramono_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMono.ttf\"\n.popsection\n"); -asm("\n.pushsection veramoit_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoIt.ttf\"\n.popsection\n"); -asm("\n.pushsection veramobd_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBd.ttf\"\n.popsection\n"); -asm("\n.pushsection veramobi_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBI.ttf\"\n.popsection\n"); -asm("\n.pushsection verase_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSe.ttf\"\n.popsection\n"); -asm("\n.pushsection verasebd_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSeBd.ttf\"\n.popsection\n"); - -// DejaVu Sans allows for Greek symbols and will be the default -asm("\n.pushsection dvsans_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans.ttf\"\n.popsection\n"); -asm("\n.pushsection dvsansit_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Oblique.ttf\"\n.popsection\n"); -asm("\n.pushsection dvsansbd_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Bold.ttf\"\n.popsection\n"); -asm("\n.pushsection dvsansbi_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-BoldOblique.ttf\"\n.popsection\n"); - -#endif - -#elif defined __APPLE__ - -// On Mac, we need a different incantation to use .incbin -asm("\t.global ___start_vera_ttf\n\t.global ___stop_vera_ttf\n___start_vera_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/Vera.ttf\"\n___stop_vera_ttf:\n"); -asm("\t.global ___start_verait_ttf\n\t.global ___stop_verait_ttf\n___start_verait_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraIt.ttf\"\n___stop_verait_ttf:\n"); -asm("\t.global ___start_verabd_ttf\n\t.global ___stop_verabd_ttf\n___start_verabd_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBd.ttf\"\n___stop_verabd_ttf:\n"); -asm("\t.global ___start_verabi_ttf\n\t.global ___stop_verabi_ttf\n___start_verabi_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBI.ttf\"\n___stop_verabi_ttf:\n"); -asm("\t.global ___start_veramono_ttf\n\t.global ___stop_veramono_ttf\n___start_veramono_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMono.ttf\"\n___stop_veramono_ttf:\n"); -asm("\t.global ___start_veramoit_ttf\n\t.global ___stop_veramoit_ttf\n___start_veramoit_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoIt.ttf\"\n___stop_veramoit_ttf:\n"); -asm("\t.global ___start_veramobd_ttf\n\t.global ___stop_veramobd_ttf\n___start_veramobd_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBd.ttf\"\n___stop_veramobd_ttf:\n"); -asm("\t.global ___start_veramobi_ttf\n\t.global ___stop_veramobi_ttf\n___start_veramobi_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBI.ttf\"\n___stop_veramobi_ttf:\n"); -asm("\t.global ___start_verase_ttf\n\t.global ___stop_verase_ttf\n___start_verase_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSe.ttf\"\n___stop_verase_ttf:\n"); -asm("\t.global ___start_verasebd_ttf\n\t.global ___stop_verasebd_ttf\n___start_verasebd_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSeBd.ttf\"\n___stop_verasebd_ttf:\n"); - -asm("\t.global ___start_dvsans_ttf\n\t.global ___stop_dvsans_ttf\n___start_dvsans_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans.ttf\"\n___stop_dvsans_ttf:\n"); -asm("\t.global ___start_dvsansit_ttf\n\t.global ___stop_dvsansit_ttf\n___start_dvsansit_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Oblique.ttf\"\n___stop_dvsansit_ttf:\n"); -asm("\t.global ___start_dvsansbd_ttf\n\t.global ___stop_dvsansbd_ttf\n___start_dvsansbd_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Bold.ttf\"\n___stop_dvsansbd_ttf:\n"); -asm("\t.global ___start_dvsansbi_ttf\n\t.global ___stop_dvsansbi_ttf\n___start_dvsansbi_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-BoldOblique.ttf\"\n___stop_dvsansbi_ttf:\n"); - -#elif defined _MSC_VER - -# include // Includes vera fonts AND DejaVu fonts. -# include - -#elif defined _mplot_WIN__INCBIN // Define this only for parsing this file with the incbin executable to create verafonts.h - -// Visual Studio doesn't allow __asm{} calls in C__ code anymore, so try Dale Weiler's incbin.h -#define INCBIN_PREFIX vf_ -#include -INCBIN(vera, "./fonts/ttf-bitstream-vera/Vera.ttf"); -INCBIN(verait, "./fonts/ttf-bitstream-vera/VeraIt.ttf"); -INCBIN(verabd, "./fonts/ttf-bitstream-vera/VeraBd.ttf"); -INCBIN(verabi, "./fonts/ttf-bitstream-vera/VeraBI.ttf"); -INCBIN(veramono, "./fonts/ttf-bitstream-vera/VeraMono.ttf"); -INCBIN(veramoit, "./fonts/ttf-bitstream-vera/VeraMoIt.ttf"); -INCBIN(veramobd, "./fonts/ttf-bitstream-vera/VeraMoBd.ttf"); -INCBIN(veramobi, "./fonts/ttf-bitstream-vera/VeraMoBI.ttf"); -INCBIN(verase, "./fonts/ttf-bitstream-vera/VeraSe.ttf"); -INCBIN(verasebd, "./fonts/ttf-bitstream-vera/VeraSeBd.ttf"); -// These translation units now have three symbols, eg: -// extern const unsigned char vf_veraData[]; -// extern const unsigned char *const vf_veraEnd; -// extern const unsigned int vf_veraSize; - -INCBIN(dvsans, "./fonts/dejavu/DejaVuSans.ttf"); -INCBIN(dvsansit, "./fonts/dejavu/DejaVuSans-Oblique.ttf"); -INCBIN(dvsansbd, "./fonts/dejavu/DejaVuSans-Bold.ttf"); -INCBIN(dvsansbi, "./fonts/dejavu/DejaVuSans-BoldOblique.ttf"); - -#else -# error "Inline assembly code for including truetype fonts in the binary only work on Linux/MacOS (and then, probably only on Intel compatible compilers. Sorry about that!" -#endif - -// These external pointers are set up by the inline assembly above -#ifndef _MSC_VER -extern const char __start_verabd_ttf[]; -extern const char __stop_verabd_ttf[]; -extern const char __start_verabi_ttf[]; -extern const char __stop_verabi_ttf[]; -extern const char __start_verait_ttf[]; -extern const char __stop_verait_ttf[]; -extern const char __start_veramobd_ttf[]; -extern const char __stop_veramobd_ttf[]; -extern const char __start_veramobi_ttf[]; -extern const char __stop_veramobi_ttf[]; -extern const char __start_veramoit_ttf[]; -extern const char __stop_veramoit_ttf[]; -extern const char __start_veramono_ttf[]; -extern const char __stop_veramono_ttf[]; -extern const char __start_verasebd_ttf[]; -extern const char __stop_verasebd_ttf[]; -extern const char __start_verase_ttf[]; -extern const char __stop_verase_ttf[]; -extern const char __start_vera_ttf[]; -extern const char __stop_vera_ttf[]; - -extern const char __start_dvsans_ttf[]; -extern const char __stop_dvsans_ttf[]; -extern const char __start_dvsansit_ttf[]; -extern const char __stop_dvsansit_ttf[]; -extern const char __start_dvsansbd_ttf[]; -extern const char __stop_dvsansbd_ttf[]; -extern const char __start_dvsansbi_ttf[]; -extern const char __stop_dvsansbi_ttf[]; -#endif - -/* - * Module starts here - */ - -export module mplot.core:visualfacebase; - -import mplot.visualcommon; -import :visualfont; -import :textfeatures; - -namespace mplot::visgl -{ - struct VisualFaceBase - { - VisualFaceBase () {} - ~VisualFaceBase () {} - - //! Set true for informational/debug messages - static constexpr bool debug_visualface = false; - - //! The FT_Face that we're managing - FT_Face face; - - //! The OpenGL character info stuff - std::map glchars; - - protected: - - void init_common (const mplot::VisualFont _font, unsigned int fontpixels, FT_Library& ft_freetype) - { - std::string fontpath = ""; -#ifdef _MSC_VER - char* userprofile = getenv ("USERPROFILE"); - std::string uppath(""); - if (userprofile != nullptr) { - uppath = std::string (userprofile); - } - - switch (_font) { - case VisualFont::DVSans: - { - fontpath = uppath + "\\AppData\\Local\\Temp\\DejaVuSans.ttf"; - this->makeTempFontFile (fontpath, vf_dvsansData, vf_dvsansEnd); - break; - } - case VisualFont::DVSansItalic: - { - fontpath = uppath + "\\AppData\\Local\\Temp\\DejaVuSans-Oblique.ttf"; - this->makeTempFontFile (fontpath, vf_dvsansitData, vf_dvsansitEnd); - break; - } - case VisualFont::DVSansBold: - { - fontpath = uppath + "\\AppData\\Local\\Temp\\DejaVuSans-Bold.ttf"; - this->makeTempFontFile (fontpath, vf_dvsansbdData, vf_dvsansbdEnd); - break; - } - case VisualFont::DVSansBoldItalic: - { - fontpath = uppath + "\\AppData\\Local\\Temp\\DejaVuSans-BoldOblique.ttf"; - this->makeTempFontFile (fontpath, vf_dvsansbiData, vf_dvsansbiEnd); - break; - } - case VisualFont::Vera: - { - fontpath = uppath + "\\AppData\\Local\\Temp\\Vera.ttf"; - this->makeTempFontFile (fontpath, vf_veraData, vf_veraEnd); - break; - } - case VisualFont::VeraItalic: - { - fontpath = uppath + "\\AppData\\Local\\Temp\\VeraIt.ttf"; - this->makeTempFontFile (fontpath, vf_veraitData, vf_veraitEnd); - break; - } - case VisualFont::VeraBold: - { - fontpath = uppath + "\\AppData\\Local\\Temp\\VeraBd.ttf"; - this->makeTempFontFile (fontpath, vf_verabdData, vf_verabdEnd); - break; - } - case VisualFont::VeraBoldItalic: - { - fontpath = uppath + "\\AppData\\Local\\Temp\\VeraBI.ttf"; - this->makeTempFontFile (fontpath, vf_verabiData, vf_verabiEnd); - break; - } - case VisualFont::VeraMono: - { - fontpath = uppath + "\\AppData\\Local\\Temp\\VeraMono.ttf"; - this->makeTempFontFile (fontpath, vf_veramonoData, vf_veramonoEnd); - break; - } - case VisualFont::VeraMonoBold: - { - fontpath = uppath + "\\AppData\\Local\\Temp\\VeraMoBd.ttf"; - this->makeTempFontFile (fontpath, vf_veramobdData, vf_veramobdEnd); - break; - } - case VisualFont::VeraMonoItalic: - { - fontpath = uppath + "\\AppData\\Local\\Temp\\VeraMoIt.ttf"; - this->makeTempFontFile (fontpath, vf_veramoitData, vf_veramoitEnd); - break; - } - case VisualFont::VeraMonoBoldItalic: - { - fontpath = uppath + "\\AppData\\Local\\Temp\\VeraMoBI.ttf"; - this->makeTempFontFile (fontpath, vf_veramobiData, vf_veramobiEnd); - break; - } - case VisualFont::VeraSerif: - { - fontpath = uppath + "\\AppData\\Local\\Temp\\VeraSe.ttf"; - this->makeTempFontFile (fontpath, vf_veraseData, vf_veraseEnd); - break; - } - case VisualFont::VeraSerifBold: - { - fontpath = uppath + "\\AppData\\Local\\Temp\\VeraSeBd.ttf"; - this->makeTempFontFile (fontpath, vf_verasebdData, vf_verasebdEnd); - break; - } - default: - { - std::cout << "ERROR::Unsupported mplot font\n"; - break; - } - } -#else // Non-windows: - switch (_font) { - case VisualFont::DVSans: - { - fontpath = "/tmp/DejaVuSans.ttf"; - this->makeTempFontFile (fontpath, __start_dvsans_ttf, __stop_dvsans_ttf); - break; - } - case VisualFont::DVSansItalic: - { - fontpath = "/tmp/DejaVuSans-Oblique.ttf"; - this->makeTempFontFile (fontpath, __start_dvsansit_ttf, __stop_dvsansit_ttf); - break; - } - case VisualFont::DVSansBold: - { - fontpath = "/tmp/DejaVuSans-Bold.ttf"; - this->makeTempFontFile (fontpath, __start_dvsansbd_ttf, __stop_dvsansbd_ttf); - break; - } - case VisualFont::DVSansBoldItalic: - { - fontpath = "/tmp/DejaVuSans-BoldOblique.ttf"; - this->makeTempFontFile (fontpath, __start_dvsansbi_ttf, __stop_dvsansbi_ttf); - break; - } - case VisualFont::Vera: - { - fontpath = "/tmp/Vera.ttf"; - this->makeTempFontFile (fontpath, __start_vera_ttf, __stop_vera_ttf); - break; - } - case VisualFont::VeraItalic: - { - fontpath = "/tmp/VeraIt.ttf"; - this->makeTempFontFile (fontpath, __start_verait_ttf, __stop_verait_ttf); - break; - } - case VisualFont::VeraBold: - { - fontpath = "/tmp/VeraBd.ttf"; - this->makeTempFontFile (fontpath, __start_verabd_ttf, __stop_verabd_ttf); - break; - } - case VisualFont::VeraBoldItalic: - { - fontpath = "/tmp/VeraBI.ttf"; - this->makeTempFontFile (fontpath, __start_verabi_ttf, __stop_verabi_ttf); - break; - } - case VisualFont::VeraMono: - { - fontpath = "/tmp/VeraMono.ttf"; - this->makeTempFontFile (fontpath, __start_veramono_ttf, __stop_veramono_ttf); - break; - } - case VisualFont::VeraMonoBold: - { - fontpath = "/tmp/VeraMoBd.ttf"; - this->makeTempFontFile (fontpath, __start_veramobd_ttf, __stop_veramobd_ttf); - break; - } - case VisualFont::VeraMonoItalic: - { - fontpath = "/tmp/VeraMoIt.ttf"; - this->makeTempFontFile (fontpath, __start_veramoit_ttf, __stop_veramoit_ttf); - break; - } - case VisualFont::VeraMonoBoldItalic: - { - fontpath = "/tmp/VeraMoBI.ttf"; - this->makeTempFontFile (fontpath, __start_veramobi_ttf, __stop_veramobi_ttf); - break; - } - case VisualFont::VeraSerif: - { - fontpath = "/tmp/VeraSe.ttf"; - this->makeTempFontFile (fontpath, __start_verase_ttf, __stop_verase_ttf); - break; - } - case VisualFont::VeraSerifBold: - { - fontpath = "/tmp/VeraSeBd.ttf"; - this->makeTempFontFile (fontpath, __start_verasebd_ttf, __stop_verasebd_ttf); - break; - } - default: - { - std::cout << "ERROR::Unsupported mplot font\n"; - break; - } - } -#endif // Windows/Non-windows - - // Keep the face as a mplot::Visual owned resource, shared by VisTextModels? - if constexpr (debug_visualface == true) { - std::cout << "FT_New_Face (ft_freetype, " << fontpath << ", 0, &this->face);\n"; - } - if (FT_New_Face (ft_freetype, fontpath.c_str(), 0, &this->face)) { - std::cout << "ERROR::FREETYPE: Failed to load font (font file may be invalid)" << std::endl; - } - - FT_Set_Pixel_Sizes (this->face, 0, fontpixels); - - // Can I check this->face for how many glyphs it has? Yes: - // std::cout << "This face has " << this->face->num_glyphs << " glyphs.\n"; - } - - //! Create a temporary font file at fontpath, using the embedded data - //! starting from filestart and extending to filenend - template - void makeTempFontFile (const std::string& fontpath, T* file_start, T* file_stop) - { - T* p; - if (!mplot::tools::fileExists (fontpath)) { - std::ofstream fout; - fout.open (fontpath.c_str(), std::ios::out | std::ios::trunc | std::ios::binary); - if (fout.is_open()) { - for (p = file_start; p < file_stop; p++) { fout << *p; } - fout.close(); - } else { - std::cout << "WARNING: Failed to open " << fontpath << "!!\n"; - } - } else { - if constexpr (debug_visualface == true) { - std::cout << "INFO: " << fontpath << " already exists, no need to re-create it\n"; - } - } - } - }; -} // namespace diff --git a/mplot/VisualFont.h b/mplot/VisualFont.h index 6ef402bc..acbcf100 100644 --- a/mplot/VisualFont.h +++ b/mplot/VisualFont.h @@ -1,4 +1,4 @@ -export module mplot.core:visualfont; +export module mplot.visualfont; /* * This is just an enumerated class that defines the fonts we pack into a mplot binary diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index b337e945..0d4c09e4 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -1,9 +1,10 @@ /*! * \file * - * Declares a VisualModel implementation class, adding multi-context-safe GLAD GL function calls. + * Declares a VisualModel base class to hold the vertices that make up some individual model object + * that can be part of an OpenGL scene. * - * This leaves a path open to having VisualModel_AltGraphicsSystem (VisualModelVulkan?). + * GL function calls are added in VisualModel.h * * \author Seb James * \date March 2025 @@ -20,13 +21,63 @@ #endif #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include -#include +#include +#include -#include +import sm.geometry_polyhedra; +import sm.quaternion; +import sm.mat; +import sm.vec; +import sm.vvec; +import sm.range; +import sm.algo; +import sm.flags; + +// Need to import common here +import mplot.visualcommon; + +//import mplot.core;// Can I avoid use of this in VisualModelBase? + +#include +#include +#include namespace mplot { + union float_bytes // for gltf output + { + float f; + uint8_t bytes[sizeof(float)]; + }; + + //! Forward declaration of a Visual class + // Right now, models need to know about VisualBase to: + // get shader progs + // set/get context + // + // Could I have a singleton that can do the work and is a separate class so taht VisualModel no + // longer needs to know about VisualBase? Visual registers its identity and the shader programs + // and the singleton could set context based on an id that the VisualModel contains? + template class VisualBase; + /*! * An OpenGL model class * @@ -39,19 +90,17 @@ namespace mplot * mechanism for managing the data which is to be visualised by the final 'Visual' object (such * as mplot::HexGridVisual or mplot::ScatterVisual) * - * The base and implementation classes underlying class VisualModel contain some common 'object - * primitives' code, such as computeSphere and computeCone, which compute the vertices that will - * make up sphere and cone, respectively. If you need to see the primitives, look at - * mplot/VisualModelBase.h + * This class contains some common 'object primitives' code, such as computeSphere and + * computeCone, which compute the vertices that will make up sphere and cone, respectively. */ template - struct VisualModel : public mplot::VisualModelBase + struct VisualModel { - VisualModel() : mplot::VisualModelBase::VisualModelBase() {} - VisualModel (const sm::vec& _offset) : mplot::VisualModelBase::VisualModelBase(_offset) {} + VisualModel() {} + VisualModel (const sm::vec _offset) { this->viewmatrix.translate (_offset); } //! destroy gl buffers in the deconstructor - virtual ~VisualModel() // clang gives -Wdelete-non-abstract-non-virtual-dtor without virtual + ~VisualModel() // clang gives -Wdelete-non-abstract-non-virtual-dtor without virtual { // Explicitly clear owned VisualTextModels this->texts.clear(); @@ -65,6 +114,7 @@ namespace mplot } } +#if 0 // Hope to get rid of bindmodel /*! * Set up the passed-in VisualTextModel with functions that need access to the parent Visual attributes. */ @@ -75,7 +125,6 @@ namespace mplot throw std::runtime_error ("Can't bind a model, because I am not bound"); } model->set_parent (this->parentVis); -#if 0 model->get_shaderprogs = &mplot::VisualBase::get_shaderprogs; model->get_gprog = &mplot::VisualBase::get_gprog; model->get_tprog = &mplot::VisualBase::get_tprog; @@ -84,70 +133,28 @@ namespace mplot model->setContext = &mplot::VisualBase::set_context; model->releaseContext = &mplot::VisualBase::release_context; -#endif - } - - void set_instance_scale (const float scl) final - { - this->instscale.set_identity(); - this->instscale.scale (scl); } - void set_instance_data (const sm::vvec>& position) final - { - sm::vvec> c = { this->instcolour }; - sm::vvec a = { 1.0f }; - sm::vvec s = { 1.0f }; - this->set_instance_data (position, c, a, s); - } - - void set_instance_data (const sm::vvec>& position, const std::array& colour, - const float alpha = 1.0f, const float scale = 1.0f) final - { - sm::vvec> c = { colour }; - sm::vvec a = { alpha }; - sm::vvec s = { scale }; - this->set_instance_data (position, c, a, s); - } - - //! Set up the instance positions and params (colour, alpha, scale). Add rotation later on. - void set_instance_data (const sm::vvec>& position, - const sm::vvec>& colour, - const sm::vvec& alpha, const sm::vvec& scale) final + /*! + * Set up the passed-in VisualTextModel with functions that need access to the parent Visual attributes. + */ + template + void bindmodel (std::unique_ptr& model) { - if (position.size() < 1) { - throw std::runtime_error ("set_instance_data: pass some instance positions in"); - } - if (position.size() > this->max_instances) { - throw std::runtime_error ("set_instance_data: Haven't reserved enough space for that"); - } - if (!this->insert_instance_data) { - throw std::runtime_error ("set_instance_data: Function insert_instance_data is not bound"); - } - if (!this->insert_instparam_data) { - throw std::runtime_error ("set_instance_data: Function insert_instparam_data is not bound"); - } - if (colour.size() != scale.size() || colour.size() != alpha.size()) { - throw std::runtime_error ("set_instance_data: params vvecs should all have same size (colour, rotn, scale)"); - } - - for (size_t i = 0; i < position.size(); ++i) { - // Get access to the SSBO in VisualResources and add the 3 floats in position[i] at - // the location defined by this->instance_start + i - this->insert_instance_data (this->instance_start + i, position[i]); - } - this->instance_count = position.size(); - - for (size_t i = 0; i < colour.size(); ++i) { - this->insert_instparam_data (this->instance_start + i, colour[i], alpha[i], scale[i]); + if (this->parentVis == nullptr) { + throw std::runtime_error ("Can't bind a model, because I am not bound"); } - this->instparam_count = colour.size(); - - this->instanced_needs_update (this->parentVis); + model->set_parent (this->parentVis); + model->get_shaderprogs = &mplot::VisualBase::get_shaderprogs; + model->get_gprog = &mplot::VisualBase::get_gprog; + model->get_tprog = &mplot::VisualBase::get_tprog; + model->setContext = &mplot::VisualBase::set_context; + model->releaseContext = &mplot::VisualBase::release_context; } +#endif //! Common code to call after the vertices have been set up. GL has to have been initialised. - void postVertexInit() final + void postVertexInit() { if (this->visual_id == std::numeric_limits::max()) { throw std::runtime_error ("visual_id is unset"); @@ -230,159 +237,6 @@ namespace mplot //! Initialize vertex buffer objects and vertex array object. Empty for 'text only' VisualModels. void initializeVertices() {}; - - /*! - * Re-initialize the buffers. Client code might have appended to - * vertexPositions/Colors/Normals and indices before calling this method. - */ - void reinit_buffers() final - { - if (this->visual_id == std::numeric_limits::max()) { - throw std::runtime_error ("visual_id is unset"); - } - GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); - - if (this->setContext != nullptr) { this->setContext (this->parentVis); } - if (this->flags.test (vm_bools::postVertexInitRequired) == true) { this->postVertexInit(); } - - // Now re-set up the VBOs - _glfn->BindVertexArray (this->vao); // carefully unbind and rebind - _glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos[this->idxVBO]); // carefully unbind and rebind - - std::size_t sz = this->indices.size() * sizeof(GLuint); - _glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices.data(), GL_STATIC_DRAW); - this->setupVBO (this->vbos[this->posnVBO], this->vertexPositions, visgl::posnLoc); - this->setupVBO (this->vbos[this->normVBO], this->vertexNormals, visgl::normLoc); - this->setupVBO (this->vbos[this->colVBO], this->vertexColors, visgl::colLoc); - - _glfn->BindVertexArray(0); // carefully unbind and rebind - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); // carefully unbind and rebind - - // Optional bounding box - if (this->flags.test (vm_bools::compute_bb)) { - _glfn->BindVertexArray (this->vao_bb); - _glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos_bb[this->idxVBO]); - - std::size_t sz = this->indices_bb.size() * sizeof(GLuint); - _glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices_bb.data(), GL_STATIC_DRAW); - this->setupVBO (this->vbos_bb[this->posnVBO], this->vpos_bb, visgl::posnLoc); - this->setupVBO (this->vbos_bb[this->normVBO], this->vnorm_bb, visgl::normLoc); - this->setupVBO (this->vbos_bb[this->colVBO], this->vcol_bb, visgl::colLoc); - - _glfn->BindVertexArray(0); - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); - } - } - - //! reinit ONLY vertexColors buffer - void reinit_colour_buffer() final - { - if (this->setContext != nullptr) { this->setContext (this->parentVis); } - if (this->flags.test (vm_bools::postVertexInitRequired) == true) { this->postVertexInit(); } - if (this->visual_id == std::numeric_limits::max()) { - throw std::runtime_error ("visual_id is unset"); - } - GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); - // Now re-set up the VBOs - _glfn->BindVertexArray (this->vao); // carefully unbind and rebind - this->setupVBO (this->vbos[this->colVBO], this->vertexColors, visgl::colLoc); - _glfn->BindVertexArray(0); // carefully unbind and rebind - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); - } - - void clearTexts() { this->texts.clear(); } - - static constexpr bool debug_render = false; - //! Render the VisualModel. Note that it is assumed that the OpenGL context has been - //! obtained by the parent Visual::render call. - void render() // not final - { - if (this->hidden() == true) { return; } - - // Execute post-vertex init at render, as GL should be available. - if (this->flags.test (vm_bools::postVertexInitRequired) == true) { this->postVertexInit(); } - - GLint prev_shader = 0; - - if (this->visual_id == std::numeric_limits::max()) { - throw std::runtime_error ("visual_id is unset"); - } - GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); - _glfn->GetIntegerv (GL_CURRENT_PROGRAM, &prev_shader); - // Ensure the correct program is in play for this VisualModel - _glfn->UseProgram (this->get_gprog(this->parentVis)); - - if (!this->indices.empty()) { - - // Enable/disable wireframe mode per-model on each render call - if (this->flags.test (vm_bools::wireframe)) { - _glfn->PolygonMode (GL_FRONT_AND_BACK, GL_LINE); - } else { - _glfn->PolygonMode (GL_FRONT_AND_BACK, GL_FILL); - } - - // It is only necessary to bind the vertex array object before rendering - // (not the vertex buffer objects) - _glfn->BindVertexArray (this->vao); - - // Pass this->float to GLSL so the model can have an alpha value. - GLint loc_a = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("alpha")); - if (loc_a != -1) { _glfn->Uniform1f (loc_a, this->alpha); } - - // The scene-view matrix - GLint loc_v = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("v_matrix")); - if (loc_v != -1) { _glfn->UniformMatrix4fv (loc_v, 1, GL_FALSE, this->scenematrix.arr.data()); } - - // the model-view matrix - GLint loc_m = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("m_matrix")); - if (loc_m != -1) { _glfn->UniformMatrix4fv (loc_m, 1, GL_FALSE, this->viewmatrix.arr.data()); } - - // the instance scaling matrix (applied to all instances) - GLint loc_s = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("s_matrix")); - if (loc_s != -1) { _glfn->UniformMatrix4fv (loc_s, 1, GL_FALSE, this->instscale.arr.data()); } - - if constexpr (debug_render) { - std::cout << "VisualModel::render: scenematrix:\n" << this->scenematrix << std::endl; - std::cout << "VisualModel::render: model viewmatrix:\n" << this->viewmatrix << std::endl; - } - - // Draw the triangles - GLint loc_is = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("instance_start")); - GLint loc_ic = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("instance_count")); - GLint loc_ipc = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("instparam_count")); - if (this->flags.test (vm_bools::instanced)) { - if (loc_is != -1) { _glfn->Uniform1i (loc_is, this->instance_start); } - if (loc_ic != -1) { _glfn->Uniform1i (loc_ic, this->instance_count); } - if (loc_ipc != -1) { _glfn->Uniform1i (loc_ipc, this->instparam_count); } - _glfn->DrawElementsInstanced (GL_TRIANGLES, static_cast(this->indices.size()), GL_UNSIGNED_INT, 0, this->instance_count); - } else { - if (loc_is != -1) { _glfn->Uniform1i (loc_is, -1); } - if (loc_ic != -1) { _glfn->Uniform1i (loc_ic, -1); } - _glfn->DrawElements (GL_TRIANGLES, static_cast(this->indices.size()), GL_UNSIGNED_INT, 0); - } - - // Unbind the VAO - _glfn->BindVertexArray(0); - - // Do the bounding box optionally - if (this->flags.test (vm_bools::compute_bb) && this->flags.test (vm_bools::show_bb) && !this->indices_bb.empty()) { - _glfn->BindVertexArray (this->vao_bb); - _glfn->DrawElements (GL_TRIANGLES, static_cast(this->indices_bb.size()), GL_UNSIGNED_INT, 0); - _glfn->BindVertexArray(0); - } - } - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); - - // Now render any VisualTextModels - _glfn->PolygonMode (GL_FRONT_AND_BACK, GL_FILL); - auto ti = this->texts.begin(); - while (ti != this->texts.end()) { (*ti)->render(); ti++; } - - _glfn->UseProgram (prev_shader); - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); - } - - /*! * Helper to make a VisualTextModel and bind it ready for use. * @@ -510,28 +364,3416 @@ namespace mplot while (ti != this->texts.end()) { (*ti)->addViewRotation (r); ti++; } } - protected: + //! Process vertices and find the bounding box + void update_bb() + { + if (this->flags.test (vm_bools::compute_bb) == false) { return; } - //! A vector of pointers to text models that should be rendered. - std::vector>> texts; + if (this->vertexPositions.size() % 3 != 0) { + throw std::runtime_error ("VisualModelBase: vertexPositions size is not divisible by 3"); + } + this->bb.search_init(); + for (std::size_t i = 0; i < this->vertexPositions.size(); i += 3) { + this->bb.update (sm::vec{ vertexPositions[i], vertexPositions[i+1], vertexPositions[i+2] }); + } + // After finding the bounding box, make up the vertices to display it: + this->computeBoundingBox(); + } - //! Set up a vertex buffer object - bind, buffer and set vertex array object attribute - void setupVBO (GLuint& buf, std::vector& dat, unsigned int bufferAttribPosition) final + /*! + * Re-initialize the buffers. Client code might have appended to + * vertexPositions/Colors/Normals and indices before calling this method. + */ + void reinit_buffers() { - std::size_t sz = dat.size() * sizeof(float); - if (this->visual_id == std::numeric_limits::max()) { throw std::runtime_error ("visual_id is unset"); } GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); - _glfn->BindBuffer (GL_ARRAY_BUFFER, buf); - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); - _glfn->BufferData (GL_ARRAY_BUFFER, sz, dat.data(), GL_STATIC_DRAW); - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); - _glfn->VertexAttribPointer (bufferAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0)); - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); - _glfn->EnableVertexAttribArray (bufferAttribPosition); - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + + if (this->setContext != nullptr) { this->setContext (this->parentVis); } + if (this->flags.test (vm_bools::postVertexInitRequired) == true) { this->postVertexInit(); } + + // Now re-set up the VBOs + _glfn->BindVertexArray (this->vao); // carefully unbind and rebind + _glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos[this->idxVBO]); // carefully unbind and rebind + + std::size_t sz = this->indices.size() * sizeof(GLuint); + _glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices.data(), GL_STATIC_DRAW); + this->setupVBO (this->vbos[this->posnVBO], this->vertexPositions, visgl::posnLoc); + this->setupVBO (this->vbos[this->normVBO], this->vertexNormals, visgl::normLoc); + this->setupVBO (this->vbos[this->colVBO], this->vertexColors, visgl::colLoc); + + _glfn->BindVertexArray(0); // carefully unbind and rebind + mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); // carefully unbind and rebind + + // Optional bounding box + if (this->flags.test (vm_bools::compute_bb)) { + _glfn->BindVertexArray (this->vao_bb); + _glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos_bb[this->idxVBO]); + + std::size_t sz = this->indices_bb.size() * sizeof(GLuint); + _glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices_bb.data(), GL_STATIC_DRAW); + this->setupVBO (this->vbos_bb[this->posnVBO], this->vpos_bb, visgl::posnLoc); + this->setupVBO (this->vbos_bb[this->normVBO], this->vnorm_bb, visgl::normLoc); + this->setupVBO (this->vbos_bb[this->colVBO], this->vcol_bb, visgl::colLoc); + + _glfn->BindVertexArray(0); + mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + } + } + + //! reinit ONLY vertexColors buffer + void reinit_colour_buffer() + { + if (this->setContext != nullptr) { this->setContext (this->parentVis); } + if (this->flags.test (vm_bools::postVertexInitRequired) == true) { this->postVertexInit(); } + if (this->visual_id == std::numeric_limits::max()) { + throw std::runtime_error ("visual_id is unset"); + } + GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); + // Now re-set up the VBOs + _glfn->BindVertexArray (this->vao); // carefully unbind and rebind + this->setupVBO (this->vbos[this->colVBO], this->vertexColors, visgl::colLoc); + _glfn->BindVertexArray(0); // carefully unbind and rebind + mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + } + + void clearTexts() { this->texts.clear(); } + + //! Clear out the model, *including text models* + void clear() + { + this->vertexPositions.clear(); + this->vertexNormals.clear(); + this->vertexColors.clear(); + this->indices.clear(); + this->clearTexts(); + this->idx = 0u; + // Clear bounding box + this->vpos_bb.clear(); + this->vnorm_bb.clear(); + this->vcol_bb.clear(); + this->indices_bb.clear(); + this->idx_bb = 0u; + + this->reinit_buffers(); + } + + //! Re-create the model - called after updating data + void reinit() + { + if (this->setContext != nullptr) { + this->setContext (this->parentVis); + } + // Fixme: Better not to clear, then repeatedly pushback here: + this->vertexPositions.clear(); + this->vertexNormals.clear(); + this->vertexColors.clear(); + this->indices.clear(); + + // Clear any bounding box too + this->vpos_bb.clear(); + this->vnorm_bb.clear(); + this->vcol_bb.clear(); + this->indices_bb.clear(); + this->idx_bb = 0u; + + // NB: Do NOT call clearTexts() here! We're only updating the model itself. + this->idx = 0u; + this->initializeVertices(); + this->update_bb(); + this->reinit_buffers(); + } + + /*! + * For some models it's important to clear the texts when reinitialising. This is NOT the + * same as VisualModel::clear() followed by initializeVertices(). For the same effect, you + * can call clearTexts() then reinit(). + */ + void reinit_with_clearTexts() + { + if (this->setContext != nullptr) { this->setContext (this->parentVis); } + this->vertexPositions.clear(); + this->vertexNormals.clear(); + this->vertexColors.clear(); + this->indices.clear(); + + this->clearTexts(); + this->idx = 0u; + + // Clear any bounding box too + this->vpos_bb.clear(); + this->vnorm_bb.clear(); + this->vcol_bb.clear(); + this->indices_bb.clear(); + this->idx_bb = 0u; + + this->initializeVertices(); + this->update_bb(); + this->reinit_buffers(); + } + + void reserve_vertices (std::size_t n_vertices) + { + this->vertexPositions.reserve (3u * n_vertices); + this->vertexNormals.reserve (3u * n_vertices); + this->vertexColors.reserve (3u * n_vertices); + this->indices.reserve (6u * n_vertices); + } + + // Make a hash of vertexPositions, etc as an identifier for this model. The hash identifies + // the model's mesh geometry for NavMesh and so the vertexColors are not important. + std::size_t hash() const + { + std::size_t h = 17; + for (std::size_t i = 0u; i < this->vertexPositions.size(); ++i) { + h = (h << 5) - 1 + std::hash{}(this->vertexPositions[i]); + } + for (std::size_t i = 0u; i < this->vertexNormals.size(); ++i) { + h = (h << 5) - 1 + std::hash{}(this->vertexNormals[i]); + } + for (std::size_t i = 0u; i < this->indices.size(); ++i) { + h = (h << 5) - 1 + std::hash{}(this->indices[i]); + } + return h; + } + + // Get a single position from vertexPositions, using the index into the vector + // interpretation of vertexPositions + sm::vec get_position (const uint32_t vec_idx) const + { + auto vp = reinterpret_cast>*>(&this->vertexPositions); + return (*vp)[vec_idx]; + } + + // Get a single normal from vertexNormals, using the index into the vector + // interpretation of vertexNormals + sm::vec get_normal (const uint32_t vec_idx) const + { + auto vn = reinterpret_cast>*>(&this->vertexNormals); + return (*vn)[vec_idx]; + } + + // Get the area of the triangle whose start index is vec_idx + float get_area (const uint32_t vec_idx0, const uint32_t vec_idx1, const uint32_t vec_idx2) const + { + auto vp = reinterpret_cast>*>(&this->vertexPositions); + auto t0 = (*vp)[vec_idx0]; + auto t1 = (*vp)[vec_idx1]; + auto t2 = (*vp)[vec_idx2]; + return sm::geometry::tri_area (t0, t1, t2); + } + + /** + * Neighbour vertex mesh code. + */ + + // Our navigation mesh data struct + std::unique_ptr navmesh; + + void build_navmesh() + { + constexpr bool debug_mn = false; + if constexpr (debug_mn) { std::cout << __func__ << " called" << std::endl; } + + if (!this->navmesh) { return; } + + // Copy the bounding box + navmesh->bb = this->bb; + + // Treat vertexPositions as a vector of vec: + auto vp = reinterpret_cast>*>(&this->vertexPositions); + + uint32_t vps = vp->size(); + std::unordered_map, std::set, sm::vec::hash> equiv_v; + uint32_t i = 0; + for (auto p : *vp) { equiv_v[p].insert (i++); } + std::map> equiv; + for (auto e : equiv_v) { equiv[*e.second.begin()] = e.second; } + if constexpr (debug_mn) { + for (auto e : equiv) { + std::cout << "build_navmesh: equiv[" << e.first << "] = "; + for (auto idx : e.second) { std::cout << idx << ","; } + std::cout << std::endl; + } + std::cout << "build_navmesh: Populated equiv which has " << equiv.size() << " vvecs" << std::endl; + } + + // Make inverse of equiv to translate from original (indices, vertexPositions) index to + // new topographic mesh index + sm::vvec navmesh_idx (vps, 0); + uint32_t vcount = 0; + i = 0; + for (auto eqs : equiv) { + vcount += eqs.second.size(); + for (auto ev : eqs.second) { + if constexpr (debug_mn) { + std::cout << "build_navmesh: set navmesh_idx[" << ev << "] = " << i << std::endl; + } + navmesh_idx[ev] = i; + } + ++i; + } + if constexpr (debug_mn) { std::cout << "build_navmesh: Created equiv inverse" << std::endl; } + + if (vcount != vps) { + std::cout << "build_navmesh: WARNING: Vertex count from equiv is " << vcount + << " which should (but does not) equal " << vps << std::endl; + } + + // Can now populate vertex, a vector of coordinates, if required, or simply access (*vp) + // as needed using equiv.first + navmesh->vertex.resize (equiv.size(), mesh::vertex{}); + i = 0; + for (auto eq : equiv) { + navmesh->vertex[i++] = { (*vp)[eq.first], std::numeric_limits::max() }; + } + + // We're turing a triangle mesh into a navmesh. Don't know what to do if there are stray vertices. + if (this->indices.size() % 3u != 0u) { + throw std::runtime_error ("Uh oh, indices size not divisible by 3!!!! Call the cops!"); + } + + // Lastly, generate edges. For which we require use of indices, which is expressed in + // terms of the old indices. That lookup is navmesh_idx. + for (uint32_t i = 0; i < this->indices.size(); i += 3) { + + // Add three halfedges for the triangle + const uint32_t hesz = navmesh->halfedge.size(); + const uint32_t he0 = hesz; + const uint32_t he1 = hesz + 1; + const uint32_t he2 = hesz + 2; + + if constexpr (debug_mn) { + std::cout << "setting halfedge["<< he0 << "] to { {" + << navmesh_idx[indices[i]] << ", " << navmesh_idx[indices[i + 1]] + << "}, nullptr, " << he1 << ", " << he2 << " }" << std::endl; + + std::cout << "setting halfedge[" << he1 << "] to { {" + << navmesh_idx[indices[i + 1]] << ", " << navmesh_idx[indices[i + 2]] + << "}, nullptr, " << he2 << ", " << he0 << " }" << std::endl; + + std::cout << "setting halfedge[" << he2 << "] to { {" + << navmesh_idx[indices[i + 2]] << ", " << navmesh_idx[indices[i]] + << "}, nullptr, " << he0 << ", " << he1 << " }" << std::endl; + } + + navmesh->halfedge.resize (hesz + 3, {}); + + // Now, could also try to identify LINES + navmesh->halfedge[he0] = { {navmesh_idx[indices[i ]], navmesh_idx[indices[i + 1]]}, std::numeric_limits::max(), he1, he2, 0u }; + navmesh->halfedge[he1] = { {navmesh_idx[indices[i + 1]], navmesh_idx[indices[i + 2]]}, std::numeric_limits::max(), he2, he0, 0u }; + navmesh->halfedge[he2] = { {navmesh_idx[indices[i + 2]], navmesh_idx[indices[i ]]}, std::numeric_limits::max(), he0, he1, 0u }; + + if constexpr (debug_mn) { + std::cout << "halfedge["<< hesz << "] contains: vi:" + << navmesh->halfedge[hesz].vi + << ", twin:" << navmesh->halfedge[hesz].twin + << ", next:" << navmesh->halfedge[hesz].next + << ", prev:" << navmesh->halfedge[hesz].prev << std::endl; + } + // A face contains just the first half edge index + mesh::face<> t = { he0 }; + + // The normal vector for this triangle could be obtained from the mesh normals, but + // we can't trust them (though they're easy to get, as we're dealing with indices + // already). However, use this to ensure that our triangle indices order is in + // agreement with mesh normal as far as direction goes. + sm::vec tn = this->get_normal (indices[i]) + this->get_normal (indices[i + 1]) + this->get_normal (indices[i + 2]) ; + tn.renormalize(); + + // Compute trinorm as well and compare with the one from the mesh - perhaps it's + // different? We really want the right normal. + const sm::vec& tv0 = navmesh->vertex[navmesh_idx[indices[i]]].p; + const sm::vec& tv1 = navmesh->vertex[navmesh_idx[indices[i + 1]]].p; + const sm::vec& tv2 = navmesh->vertex[navmesh_idx[indices[i + 2]]].p; + sm::vec nx = (tv1 - tv0); + sm::vec ny = (tv2 - tv0); + sm::vec n = nx.cross (ny); + n.renormalize(); + + // Check rotational sense of triangles + if (n.dot (tn) < 0.0f) { + std::cout << "Swap order of triangle with he " << he0 << std::endl; + // Swap first and last half edge + navmesh->halfedge[he0].vi.rotate(); + navmesh->halfedge[he1].vi.rotate(); + navmesh->halfedge[he2].vi.rotate(); + } + navmesh->triangles.push_back (t); + } + if constexpr (debug_mn) { + std::cout << "build_navmesh: Created triangles (" << navmesh->halfedge.size() << " halfedges)" << std::endl; + } + + navmesh->compute_neighbour_relations(); // finds the halfedge twins + } + + /*! + * Post-process vertices to generate a neighbour relationship mesh suitable for navigation. + * + * \param navmesh_dir The directory into which to store/read the navmesh data file. + */ + void make_navmesh (std::string navmesh_dir = "") + { + if (this->navmesh) { return; } // already made it + + if (this->flags.test (vm_bools::compute_bb) == false) { + throw std::runtime_error ("make_navmesh requires compute_bb flag to be true"); + } + this->update_bb(); + + // Create a new navmesh + this->navmesh = std::make_unique(); + + // Have we got a pre-computed navmesh file for the halfedge twin relationships? + uint64_t h = this->hash(); + if (navmesh_dir.empty()) { + navmesh_dir = mplot::tools::getTmpPath(); + } else { + if (navmesh_dir.back() != '/') { navmesh_dir += "/"; } + } + std::string filename = navmesh_dir + std::string("navmesh_") + std::to_string (h); + std::string filename_pre_boundary = filename + ".pre"; + + constexpr bool just_mark = true; + if (mplot::tools::fileExists (filename)) { + this->navmesh->load (filename); + std::cout << "Full test...\n"; + this->navmesh->test(); + + } else if (mplot::tools::fileExists (filename_pre_boundary)) { + std::cout << "Pre-boundary navmesh\n"; + this->navmesh->load (filename_pre_boundary); + this->navmesh->add_boundary_halfedges(); + this->navmesh->test (just_mark); + this->navmesh->save (filename); + } else { + std::cout << "Building NavMesh to save into file " << filename << std::endl; + this->build_navmesh(); + this->navmesh->save (filename_pre_boundary); + this->navmesh->add_boundary_halfedges(); + this->navmesh->test (just_mark); + this->navmesh->save (filename); + } + } + + /** + * End neighbour vertex mesh code + */ + + /*! + * A function to call initialiseVertices and postVertexInit after any necessary attributes + * have been set (see, for example, setting the colour maps up in VisualDataModel). + */ + void finalize() + { + if (this->setContext != nullptr) { this->setContext (this->parentVis); } + this->initializeVertices(); + this->update_bb(); + this->flags.set (vm_bools::postVertexInitRequired, true); + // Release context after creating and finalizing this VisualModel. On Visual::render(), + // context will be re-acquired. + if (this->releaseContext != nullptr) { this->releaseContext (this->parentVis); } + } + + static constexpr bool debug_render = false; + //! Render the VisualModel. Note that it is assumed that the OpenGL context has been + //! obtained by the parent Visual::render call. + virtual void render() // not final + { + if (this->hidden() == true) { return; } + + // Execute post-vertex init at render, as GL should be available. + if (this->flags.test (vm_bools::postVertexInitRequired) == true) { this->postVertexInit(); } + + GLint prev_shader = 0; + + if (this->visual_id == std::numeric_limits::max()) { + throw std::runtime_error ("visual_id is unset"); + } + GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); + _glfn->GetIntegerv (GL_CURRENT_PROGRAM, &prev_shader); + // Ensure the correct program is in play for this VisualModel + _glfn->UseProgram (this->get_gprog(this->parentVis)); + + if (!this->indices.empty()) { + + // Enable/disable wireframe mode per-model on each render call + if (this->flags.test (vm_bools::wireframe)) { + _glfn->PolygonMode (GL_FRONT_AND_BACK, GL_LINE); + } else { + _glfn->PolygonMode (GL_FRONT_AND_BACK, GL_FILL); + } + + // It is only necessary to bind the vertex array object before rendering + // (not the vertex buffer objects) + _glfn->BindVertexArray (this->vao); + + // Pass this->float to GLSL so the model can have an alpha value. + GLint loc_a = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("alpha")); + if (loc_a != -1) { _glfn->Uniform1f (loc_a, this->alpha); } + + // The scene-view matrix + GLint loc_v = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("v_matrix")); + if (loc_v != -1) { _glfn->UniformMatrix4fv (loc_v, 1, GL_FALSE, this->scenematrix.arr.data()); } + + // the model-view matrix + GLint loc_m = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("m_matrix")); + if (loc_m != -1) { _glfn->UniformMatrix4fv (loc_m, 1, GL_FALSE, this->viewmatrix.arr.data()); } + + // the instance scaling matrix (applied to all instances) + GLint loc_s = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("s_matrix")); + if (loc_s != -1) { _glfn->UniformMatrix4fv (loc_s, 1, GL_FALSE, this->instscale.arr.data()); } + + if constexpr (debug_render) { + std::cout << "VisualModel::render: scenematrix:\n" << this->scenematrix << std::endl; + std::cout << "VisualModel::render: model viewmatrix:\n" << this->viewmatrix << std::endl; + } + + // Draw the triangles + GLint loc_is = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("instance_start")); + GLint loc_ic = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("instance_count")); + GLint loc_ipc = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("instparam_count")); + if (this->flags.test (vm_bools::instanced)) { + if (loc_is != -1) { _glfn->Uniform1i (loc_is, this->instance_start); } + if (loc_ic != -1) { _glfn->Uniform1i (loc_ic, this->instance_count); } + if (loc_ipc != -1) { _glfn->Uniform1i (loc_ipc, this->instparam_count); } + _glfn->DrawElementsInstanced (GL_TRIANGLES, static_cast(this->indices.size()), GL_UNSIGNED_INT, 0, this->instance_count); + } else { + if (loc_is != -1) { _glfn->Uniform1i (loc_is, -1); } + if (loc_ic != -1) { _glfn->Uniform1i (loc_ic, -1); } + _glfn->DrawElements (GL_TRIANGLES, static_cast(this->indices.size()), GL_UNSIGNED_INT, 0); + } + + // Unbind the VAO + _glfn->BindVertexArray(0); + + // Do the bounding box optionally + if (this->flags.test (vm_bools::compute_bb) && this->flags.test (vm_bools::show_bb) && !this->indices_bb.empty()) { + _glfn->BindVertexArray (this->vao_bb); + _glfn->DrawElements (GL_TRIANGLES, static_cast(this->indices_bb.size()), GL_UNSIGNED_INT, 0); + _glfn->BindVertexArray(0); + } + } + mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + + // Now render any VisualTextModels + _glfn->PolygonMode (GL_FRONT_AND_BACK, GL_FILL); + auto ti = this->texts.begin(); + while (ti != this->texts.end()) { (*ti)->render(); ti++; } + + _glfn->UseProgram (prev_shader); + mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + } + + //! Setter for the viewmatrix + void setViewMatrix (const sm::mat& mv) { this->viewmatrix = mv; } + //! And a getter + sm::mat getViewMatrix() const { return this->viewmatrix; } + //! Pre or post-multiply + void postmultViewMatrix (const sm::mat& m) { this->viewmatrix = this->viewmatrix * m; } + void premultViewMatrix (const sm::mat& m) { this->viewmatrix = m * this->viewmatrix; } + + void scaleViewMatrix (const float by) { this->viewmatrix.scale (by); } + + virtual void setSceneMatrixTexts (const sm::mat& sv) = 0; + + //! When setting the scene matrix, also have to set the text's scene matrices. + void setSceneMatrix (const sm::mat& sv) + { + this->scenematrix = sv; + this->setSceneMatrixTexts (sv); + } + + virtual void setSceneTranslationTexts (const sm::vec& v0) = 0; + + //! Set a translation into the scene and into any child texts + template requires (N == 3) || (N == 4) + void setSceneTranslation (const sm::vec& v0) + { + this->scenematrix.set_identity(); + this->scenematrix.translate (v0); + if constexpr (N == 4) { + this->setSceneTranslationTexts (v0.less_one_dim()); + } else { + this->setSceneTranslationTexts (v0); + } + } + + //! Set a translation (only) into the scene view matrix + template requires (N == 3) || (N == 4) + void addSceneTranslation (const sm::vec& v0) { this->scenematrix.pretranslate (v0); } + + //! Set a rotation (only) into the scene view matrix + void setSceneRotation (const sm::quaternion& r) + { + this->scenematrix.set_identity(); + this->scenematrix.rotate (r); + } + + //! Add a rotation to the scene view matrix + void addSceneRotation (const sm::quaternion& r) { this->scenematrix.rotate (r); } + + //! Set a translation to the model view matrix + template requires (N == 3) || (N == 4) + void setViewTranslation (const sm::vec& v0) + { + this->viewmatrix.set_identity(); + this->viewmatrix.translate (v0); + } + + //! Add a translation to the model view matrix + template requires (N == 3) || (N == 4) + void addViewTranslation (const sm::vec& v0) { this->viewmatrix.pretranslate (v0); } + + //! Set a rotation (only) into the view, but keep texts fixed + void setViewRotationFixTexts (const sm::quaternion& r) + { + sm::vec<> os = this->viewmatrix.translation(); + this->viewmatrix.set_identity(); + this->viewmatrix.translate (os); + this->viewmatrix.rotate (r); + } + + virtual void setViewRotationTexts (const sm::quaternion& r) = 0; + + //! Set a rotation (only) into the view + void setViewRotation (const sm::quaternion& r) + { + sm::vec<> os = this->viewmatrix.translation(); + this->viewmatrix.set_identity(); + this->viewmatrix.translate (os); + this->viewmatrix.rotate (r); + this->setViewRotationTexts (r); + } + + virtual void addViewRotationTexts (const sm::quaternion& r) = 0; + + //! Apply a further rotation to the model view matrix + void addViewRotation (const sm::quaternion& r) + { + this->viewmatrix.rotate (r); + this->addViewRotationTexts (r); + } + + //! Apply a further rotation to the model view matrix, but keep texts fixed + void addViewRotationFixTexts (const sm::quaternion& r) + { + this->viewmatrix.rotate (r); + } + + // The alpha attribute accessors + void setAlpha (const float _a) { this->alpha = _a; } + float getAlpha() const { return this->alpha; } + void incAlpha() + { + this->alpha += 0.1f; + this->alpha = this->alpha > 1.0f ? 1.0f : this->alpha; + } + void decAlpha() + { + this->alpha -= 0.1f; + this->alpha = this->alpha < 0.0f ? 0.0f : this->alpha; + } + + // The hide attribute accessors + void setHide (const bool _h = true) { this->flags.set (vm_bools::hide, _h); } + void toggleHide() { this->flags.flip (vm_bools::hide); } + float hidden() const { return this->flags.test (vm_bools::hide); } + + /* + * Methods used by Visual::savegltf() + */ + + //! Get model translation in a json-friendly string + std::string translation_str() { return this->viewmatrix.translation().str_mat(); } + //! A getter for the viewmatrix translation of the origin (would be same as viewmatrix.translation) + sm::vec get_viewmatrix_origin() const + { + return (this->viewmatrix * sm::vec{0,0,0}).less_one_dim(); + } + //! The centre of mass of the bounding box may not be the VisualModel's origin + sm::vec get_viewmatrix_bb_centre() const + { + return (this->viewmatrix * this->bb.mid()).less_one_dim(); + } + + //! Apply the viewmatrix to the model's bounding box and return it + sm::range> get_viewmatrix_modelbb() const + { + sm::range> vmbb; + vmbb.min = (this->viewmatrix * this->bb.min).less_one_dim(); + vmbb.max = (this->viewmatrix * this->bb.max).less_one_dim(); + return vmbb; + } + + //! Return the number of elements in this->indices + std::size_t indices_size() { return this->indices.size(); } + float indices_max() { return this->idx_max; } + float indices_min() { return this->idx_min; } + std::size_t indices_bytes() { return this->indices.size() * sizeof (GLuint); } + //! Return base64 encoded version of indices + std::string indices_base64() + { + std::vector idx_bytes (this->indices.size() << 2, 0); + std::size_t b = 0u; + for (auto i : this->indices) { + idx_bytes[b++] = i & 0xff; + idx_bytes[b++] = i >> 8 & 0xff; + idx_bytes[b++] = i >> 16 & 0xff; + idx_bytes[b++] = i >> 24 & 0xff; + } + return base64::encode (idx_bytes); + } + + /*! + * Find the extents of this VisualModel, returning it as the x range, the y range and the z range. + */ + sm::vec, 3> extents() + { + sm::vec, 3> axis_extents; + for (unsigned int i = 0; i < 3; ++i) { axis_extents[i].search_init(); } + for (unsigned int j = 0; j < static_cast(this->vertexPositions.size() - 2); j += 3) { + for (unsigned int i = 0; i < 3; ++i) { axis_extents[i].update (this->vertexPositions[j+i]); } + } + return axis_extents; + } + + /*! + * Compute the max and min values of indices and vertexPositions/Colors/Normals for use + * when saving gltf files + */ + void computeVertexMaxMins() + { + // Compute index maxmins + for (std::size_t i = 0u; i < this->indices.size(); ++i) { + idx_max = this->indices[i] > idx_max ? this->indices[i] : idx_max; + idx_min = this->indices[i] < idx_min ? this->indices[i] : idx_min; + } + // Check every 0th entry in vertex Positions, every 1st, etc for max in the + + if (this->vertexPositions.size() != this->vertexColors.size() + ||this->vertexPositions.size() != this->vertexNormals.size()) { + throw std::runtime_error ("Expect vertexPositions, Colors and Normals vectors all to have same size"); + } + + for (std::size_t i = 0u; i < this->vertexPositions.size(); i+=3u) { + vpos_maxes[0] = (vertexPositions[i] > vpos_maxes[0]) ? vertexPositions[i] : vpos_maxes[0]; + vpos_maxes[1] = (vertexPositions[i+1] > vpos_maxes[1]) ? vertexPositions[i+1] : vpos_maxes[1]; + vpos_maxes[2] = (vertexPositions[i+2] > vpos_maxes[2]) ? vertexPositions[i+2] : vpos_maxes[2]; + vcol_maxes[0] = (vertexColors[i] > vcol_maxes[0]) ? vertexColors[i] : vcol_maxes[0]; + vcol_maxes[1] = (vertexColors[i+1] > vcol_maxes[1]) ? vertexColors[i+1] : vcol_maxes[1]; + vcol_maxes[2] = (vertexColors[i+2] > vcol_maxes[2]) ? vertexColors[i+2] : vcol_maxes[2]; + vnorm_maxes[0] = (vertexNormals[i] > vnorm_maxes[0]) ? vertexNormals[i] : vnorm_maxes[0]; + vnorm_maxes[1] = (vertexNormals[i+1] > vnorm_maxes[1]) ? vertexNormals[i+1] : vnorm_maxes[1]; + vnorm_maxes[2] = (vertexNormals[i+2] > vnorm_maxes[2]) ? vertexNormals[i+2] : vnorm_maxes[2]; + + vpos_mins[0] = (vertexPositions[i] < vpos_mins[0]) ? vertexPositions[i] : vpos_mins[0]; + vpos_mins[1] = (vertexPositions[i+1] < vpos_mins[1]) ? vertexPositions[i+1] : vpos_mins[1]; + vpos_mins[2] = (vertexPositions[i+2] < vpos_mins[2]) ? vertexPositions[i+2] : vpos_mins[2]; + vcol_mins[0] = (vertexColors[i] < vcol_mins[0]) ? vertexColors[i] : vcol_mins[0]; + vcol_mins[1] = (vertexColors[i+1] < vcol_mins[1]) ? vertexColors[i+1] : vcol_mins[1]; + vcol_mins[2] = (vertexColors[i+2] < vcol_mins[2]) ? vertexColors[i+2] : vcol_mins[2]; + vnorm_mins[0] = (vertexNormals[i] < vnorm_mins[0]) ? vertexNormals[i] : vnorm_mins[0]; + vnorm_mins[1] = (vertexNormals[i+1] < vnorm_mins[1]) ? vertexNormals[i+1] : vnorm_mins[1]; + vnorm_mins[2] = (vertexNormals[i+2] < vnorm_mins[2]) ? vertexNormals[i+2] : vnorm_mins[2]; + } + } + + std::size_t vpos_size() { return this->vertexPositions.size(); } + std::string vpos_max() { return this->vpos_maxes.str_mat(); } + std::string vpos_min() { return this->vpos_mins.str_mat(); } + std::size_t vpos_bytes() { return this->vertexPositions.size() * sizeof (float); } + std::string vpos_base64() + { + std::vector _bytes (this->vertexPositions.size() << 2, 0); + std::size_t b = 0u; + float_bytes fb; + for (auto i : this->vertexPositions) { + fb.f = i; + _bytes[b++] = fb.bytes[0]; + _bytes[b++] = fb.bytes[1]; + _bytes[b++] = fb.bytes[2]; + _bytes[b++] = fb.bytes[3]; + } + return base64::encode (_bytes); + } + std::size_t next_vpos_idx = 0; + void init_vpos_accessor() { this->next_vpos_idx = 0; } + sm::vec get_next_vpos() + { + sm::vec pos; + pos.set_from (std::numeric_limits::max()); + if (this->next_vpos_idx < this->vertexPositions.size()) { + sm::vec tmp = { + this->vertexPositions[this->next_vpos_idx], + this->vertexPositions[this->next_vpos_idx + 1], + this->vertexPositions[this->next_vpos_idx + 2] + }; + + pos = (this->viewmatrix * tmp).less_one_dim(); + this->next_vpos_idx += 3; + } + return pos; + } + + std::size_t vcol_size() { return this->vertexColors.size(); } + std::string vcol_max() { return this->vcol_maxes.str_mat(); } + std::string vcol_min() { return this->vcol_mins.str_mat(); } + std::size_t vcol_bytes() { return this->vertexColors.size() * sizeof (float); } + std::string vcol_base64() + { + std::vector _bytes (this->vertexColors.size() << 2, 0); + std::size_t b = 0u; + float_bytes fb; + for (auto i : this->vertexColors) { + fb.f = i; + _bytes[b++] = fb.bytes[0]; + _bytes[b++] = fb.bytes[1]; + _bytes[b++] = fb.bytes[2]; + _bytes[b++] = fb.bytes[3]; + } + return base64::encode (_bytes); + } + std::size_t vnorm_size() { return this->vertexNormals.size(); } + std::string vnorm_max() { return this->vnorm_maxes.str_mat(); } + std::string vnorm_min() { return this->vnorm_mins.str_mat(); } + std::size_t vnorm_bytes() { return this->vertexNormals.size() * sizeof (float); } + std::string vnorm_base64() + { + std::vector _bytes (this->vertexNormals.size()<<2, 0); + std::size_t b = 0u; + float_bytes fb; + for (auto i : this->vertexNormals) { + fb.f = i; + _bytes[b++] = fb.bytes[0]; + _bytes[b++] = fb.bytes[1]; + _bytes[b++] = fb.bytes[2]; + _bytes[b++] = fb.bytes[3]; + } + return base64::encode (_bytes); + } + std::size_t next_vnorm_idx = 0; + void init_vnorm_accessor() { this->next_vnorm_idx = 0; } + sm::vec get_next_vnorm() + { + sm::vec pos; + pos.set_from (std::numeric_limits::max()); + if (this->next_vnorm_idx < this->vertexPositions.size()) { + pos = { this->vertexPositions[this->next_vnorm_idx], + this->vertexPositions[this->next_vnorm_idx + 1], + this->vertexPositions[this->next_vnorm_idx + 2] }; + this->next_vnorm_idx += 3; + } + return pos; + } + // end Visual::savegltf() methods + + // A VisualModel may be given a name + std::string name = {}; + + // The mplot::Visual ID to which I belong. max means unset. + uint32_t visual_id = std::numeric_limits::max(); + + //! The current indices index + GLuint idx = 0u; + GLuint idx_bb = 0u; + + /*! + * This is the upper limit for instance_count. We reserve max_isntances of space in the SSBO. + * + * Max number of instances in a model. Each *model* has to reserve space in the SSBOs which + * are managed by VisualResources. VisualResources::max_instances must be larger than this. + */ + unsigned int max_instances = 16 * 1024; + //! The offset into the SSBOs for the instance data for this VisualModel + unsigned int instance_start = 0; + //! If drawing with instancing, how many instances? <= this->max_instances + unsigned int instance_count = 0; + //! If drawing with instancing, how many params will be used (these will be cycled through + //! per-instance and there may be fewer than instance_count parameters) + unsigned int instparam_count = 0; +#if 0 + /*! + * A function that will be runtime defined to get_shaderprogs from a pointer to + * Visual (saving a boilerplate argument and avoiding that killer circular + * dependency at the cost of one line of boilerplate in client programs) + */ + std::function*)> get_shaderprogs; + //! Get the graphics shader prog id + std::function*)> get_gprog; + //! Get the text shader prog id + std::function*)> get_tprog; + + //! Set OpenGL context. Should call parentVis->setContext(). + std::function*)> setContext; + //! Release OpenGL context. Should call parentVis->releaseContext(). + std::function*)> releaseContext; + + //! Init the SSBOs for instanced rendering + std::function*, const unsigned int)> init_instance_data; + std::function&)> insert_instance_data; + std::function&, const float, const float)> insert_instparam_data; + std::function*)> instanced_needs_update; +#endif + + //! Set the scaling matrix for all instances + void set_instance_scale (const float scl) + { + this->instscale.set_identity(); + this->instscale.scale (scl); + } + + //! Set up the instance positions (with default params for colour, rotn, scale) + void set_instance_data (const sm::vvec>& position) + { + sm::vvec> c = { this->instcolour }; + sm::vvec a = { 1.0f }; + sm::vvec s = { 1.0f }; + this->set_instance_data (position, c, a, s); + } + + //! Set instance positions, with an array containing colour, alpha and scale values to apply + //! to the instances. The size of colour, alpha and scale must match, but it may be of a + //! different size to position. + void set_instance_data (const sm::vvec>& position, const std::array& colour, + const float alpha = 1.0f, const float scale = 1.0f) + { + sm::vvec> c = { colour }; + sm::vvec a = { alpha }; + sm::vvec s = { scale }; + this->set_instance_data (position, c, a, s); + } + + //! Set up the instance positions and params (colour, alpha, scale). Add rotation later on. + void set_instance_data (const sm::vvec>& position, + const sm::vvec>& colour, + const sm::vvec& alpha, const sm::vvec& scale) + { + if (position.size() < 1) { + throw std::runtime_error ("set_instance_data: pass some instance positions in"); + } + if (position.size() > this->max_instances) { + throw std::runtime_error ("set_instance_data: Haven't reserved enough space for that"); + } + if (!this->insert_instance_data) { + throw std::runtime_error ("set_instance_data: Function insert_instance_data is not bound"); + } + if (!this->insert_instparam_data) { + throw std::runtime_error ("set_instance_data: Function insert_instparam_data is not bound"); + } + if (colour.size() != scale.size() || colour.size() != alpha.size()) { + throw std::runtime_error ("set_instance_data: params vvecs should all have same size (colour, rotn, scale)"); + } + + for (size_t i = 0; i < position.size(); ++i) { + // Get access to the SSBO in VisualResources and add the 3 floats in position[i] at + // the location defined by this->instance_start + i + this->insert_instance_data (this->instance_start + i, position[i]); + } + this->instance_count = position.size(); + + for (size_t i = 0; i < colour.size(); ++i) { + this->insert_instparam_data (this->instance_start + i, colour[i], alpha[i], scale[i]); + } + this->instparam_count = colour.size(); + + this->instanced_needs_update (this->parentVis); + } + + +#if 0 + //! Update the instance positions and params (colour, rotn, scale) in a range + virtual void update_instance_data (const sm::vvec>& points, const sm::vvec& data, + std::size_t i_s, std::size_t i_e) = 0; +#endif + //! Setter for the parent pointer, parentVis + void set_parent (mplot::VisualBase* _vis) + { + if (this->parentVis != nullptr) { throw std::runtime_error ("VisualModel: Set the parent pointer once only!"); } + this->parentVis = _vis; + } + + // Flags defaults. + constexpr sm::flags flags_defaults() + { + sm::flags _flags; + _flags.set (vm_bools::postVertexInitRequired, false); + _flags.set (vm_bools::twodimensional, false); + _flags.set (vm_bools::hide, false); + _flags.set (vm_bools::wireframe, false); + _flags.set (vm_bools::show_bb, false); + _flags.set (vm_bools::compute_bb, true); + return _flags; + } + + // State/options flags + sm::flags flags = flags_defaults(); + + // Setters for flags + void show_bb (const bool val) { this->flags.set (vm_bools::show_bb, val); } + void compute_bb (const bool val) { this->flags.set (vm_bools::compute_bb, val); } + + //! A range can be used for a bounding box for this VisualModel + sm::range> bb; + std::array colour_bb = mplot::colour::grey90; + + void twodimensional (const bool val) { this->flags.set (vm_bools::twodimensional, val); } + bool twodimensional() const { return this->flags.test (vm_bools::twodimensional); } + + void wireframe (const bool val) { this->flags.set (vm_bools::wireframe, val); } + bool wireframe() const { return this->flags.test (vm_bools::wireframe); } + + void instanced (const bool val) { this->flags.set (vm_bools::instanced, val); } + bool instanced() const { return this->flags.test (vm_bools::instanced); } + + //! Getter for vertex positions (for mplot::NormalsVisual) + std::vector getVertexPositions() { return this->vertexPositions; } + //! Getter for vertex normals (for mplot::NormalsVisual) + std::vector getVertexNormals() { return this->vertexNormals; } + std::vector getVertexColors() { return this->vertexColors; } + + protected: + + //! The model-specific view matrix. Used to transform the pose of the model in the scene. + sm::mat viewmatrix = {}; + /*! + * The scene view matrix. Each VisualModel has a copy of the scenematrix. It's set in + * Visual::render. Different VisualModels may have different scenematrices (for example, the + * CoordArrows has a different scenematrix from other VisualModels, and models marked + * 'twodimensional' also have a different scenematrix). + */ + sm::mat scenematrix = {}; + + /*! + * Instance scaling. This matrix can be used to control the scale of all instances of an + * instanced VisualModel + */ + sm::mat instscale = {}; + + /*! + * The colour for all instances. This is used if you don't set colour in your instance params. + */ + std::array instcolour = mplot::colour::yellow; + + //! Contains the positions within the vbo array of the different vertex buffer objects + enum VBOPos { posnVBO, normVBO, colVBO, idxVBO, numVBO }; + + /* + * Compute positions and colours of vertices for the hexes and store in these: + */ + + //! The OpenGL Vertex Array Object + GLuint vao = 0; + + //! Vertex Buffer Objects stored in an array + std::unique_ptr vbos; + + //! CPU-side data for indices + std::vector indices = {}; + //! CPU-side data for vertex positions + std::vector vertexPositions = {}; + //! CPU-side data for vertex normals + std::vector vertexNormals = {}; + //! CPU-side data for vertex colours + std::vector vertexColors = {}; + + // OpenGL arrays for the bounding box, if needed + GLuint vao_bb = 0; + std::unique_ptr vbos_bb; + std::vector indices_bb = {}; + std::vector vpos_bb = {}; + std::vector vnorm_bb = {}; + std::vector vcol_bb = {}; + + static constexpr float _max = std::numeric_limits::max(); + static constexpr float _low = std::numeric_limits::lowest(); + + // The max and min values in the next 8 attributes are only computed if gltf files are going + // to be output by Visual::savegltf() + + //! Max values of 0th, 1st and 2nd coordinates in vertexPositions + sm::vec vpos_maxes = { _low, _low, _low }; // fixme: same as bounding box! + //! Min values in vertexPositions + sm::vec vpos_mins = { _max, _max, _max }; + sm::vec vcol_maxes = { _low, _low, _low }; + sm::vec vcol_mins = { _max, _max, _max }; + sm::vec vnorm_maxes = { _low, _low, _low }; + sm::vec vnorm_mins = { _max, _max, _max }; + //! Max value in indices + GLuint idx_max = 0u; + //! Min value in indices. + GLuint idx_min = std::numeric_limits::max(); + + //! A model-wide alpha value for the shader + float alpha = 1.0f; + + // The mplot::VisualBase in which this model exists. + mplot::VisualBase* parentVis = nullptr; + + //! A vector of pointers to text models that should be rendered. + std::vector>> texts; + + //! Set up a vertex buffer object - bind, buffer and set vertex array object attribute + void setupVBO (GLuint& buf, std::vector& dat, unsigned int bufferAttribPosition) final + { + std::size_t sz = dat.size() * sizeof(float); + + if (this->visual_id == std::numeric_limits::max()) { + throw std::runtime_error ("visual_id is unset"); + } + GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); + _glfn->BindBuffer (GL_ARRAY_BUFFER, buf); + mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + _glfn->BufferData (GL_ARRAY_BUFFER, sz, dat.data(), GL_STATIC_DRAW); + mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + _glfn->VertexAttribPointer (bufferAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0)); + mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + _glfn->EnableVertexAttribArray (bufferAttribPosition); + mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + } + + //! Push three floats onto the vector of floats \a vp + void vertex_push (const float& x, const float& y, const float& z, std::vector& vp) + { + vp.emplace_back (x); + vp.emplace_back (y); + vp.emplace_back (z); + } + //! Push array of 3 floats onto the vector of floats \a vp + template requires (N == 3 || N == 4) + void vertex_push (const std::array& arr, std::vector& vp) + { + vp.emplace_back (arr[0]); + vp.emplace_back (arr[1]); + vp.emplace_back (arr[2]); + } + //! Push sm::vec of 3 floats onto the vector of floats \a vp + template requires (N == 3 || N == 4) + void vertex_push (const sm::vec& vec, std::vector& vp) + { + vp.emplace_back (vec[0]); + vp.emplace_back (vec[1]); + vp.emplace_back (vec[2]); + } + + //! Set up a vertex buffer object - bind, buffer and set vertex array object attribute + virtual void setupVBO (GLuint& buf, std::vector& dat, unsigned int bufferAttribPosition) = 0; + + protected: + /*! + * Add the given meshgroup to this VisualModel + */ + void computeMeshgroup (const mplot::meshgroup& mg) + { + mg.validate(); + + bool single_colr = mg.colours.empty(); + for (uint32_t i = 0; i < mg.positions.size(); ++i) { + // We apply mg.transform *here*, rather than writing it into the viewmatrix. This is + // because other elements of this visual model may be added with the assumption of an + // identity viewmatrix. + this->vertex_push (mg.transform * mg.positions[i], this->vertexPositions); + this->vertex_push (mg.transform * mg.normals[i], this->vertexNormals); + if (single_colr) { + this->vertex_push (mg.single_colour, this->vertexColors); + } else { + this->vertex_push (mg.colours[i], this->vertexColors); + } + } + for (uint32_t i = 0; i < mg.indices.size(); ++i) { + this->indices.push_back (mg.indices[i] + this->idx); + } + this->idx += mg.positions.size(); + } + + /** + * START vertex/index computation code + * + * ALL methods below this point are for computing vertices. + * + * The metheds compute vertexPositions/Normals/Colors along with indices in a form suitable + * for use with GL's DrawElements (or DrawElementsInstanced) drawing call. + */ + + /*! + * Create a tube from \a start to \a end, with radius \a r and a colour which + * transitions from the colour \a colStart to \a colEnd. + * + * This version simply sub-calls into computeFlaredTube which will randomly choose the angle + * of the vertices around the centre of each end cap. + * + * \param idx The index into the 'vertex array' + * \param start The start of the tube + * \param end The end of the tube + * \param colStart The tube starting colour + * \param colEnd The tube's ending colour + * \param r Radius of the tube + * \param segments Number of segments used to render the tube + */ + void computeTube (sm::vec start, sm::vec end, + std::array colStart, std::array colEnd, + float r = 1.0f, int segments = 12) + { + this->computeFlaredTube (start, end, colStart, colEnd, r, r, segments); + } + + /*! + * Compute a tube. This version requires unit vectors for orientation of the + * tube end faces/vertices (useful for graph markers). The other version uses a + * randomly chosen vector to do this. + * + * Create a tube from \a start to \a end, with radius \a r and a colour which + * transitions from the colour \a colStart to \a colEnd. + * + * \param start The start of the tube + * \param end The end of the tube + * \param _ux a vector in the x axis direction for the end face + * \param _uy a vector in the y axis direction. _ux ^ _uy gives the end cap normal + * \param colStart The tube starting colour + * \param colEnd The tube's ending colour + * \param r Radius of the tube + * \param segments Number of segments used to render the tube + * \param rotation A rotation in the _ux/_uy plane to orient the vertices of the + * tube. Useful if this is to be a short tube used as a graph marker. + * \param bb If true, write into the bounding box arrays, not the main ones + */ + void computeTube (sm::vec start, sm::vec end, + sm::vec _ux, sm::vec _uy, + std::array colStart, std::array colEnd, + float r = 1.0f, int segments = 12, float rotation = 0.0f, bool bb = false) + { + // The vector from start to end defines direction of the tube + sm::vec vstart = start; + sm::vec vend = end; + + // v is a face normal + sm::vec v = _ux.cross(_uy); + v.renormalize(); + + // If bounding box, populate different buffers: + std::vector& vp = bb ? this->vpos_bb : this->vertexPositions; + std::vector& vn = bb ? this->vnorm_bb : this->vertexNormals; + std::vector& vc = bb ? this->vcol_bb : this->vertexColors; + std::vector& idcs = bb ? this->indices_bb : this->indices; + GLuint& _idx = bb ? this->idx_bb : this->idx; + + // Push the central point of the start cap - this is at location vstart + this->vertex_push (vstart, vp); + this->vertex_push (-v, vn); + this->vertex_push (colStart, vc); + + // Start cap vertices (a triangle fan) + for (int j = 0; j < segments; j++) { + // t is the angle of the segment + float t = rotation + j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = _ux * std::sin(t) * r + _uy * std::cos(t) * r; + this->vertex_push (vstart+c, vp); + this->vertex_push (-v, vn); + this->vertex_push (colStart, vc); + } + + // Intermediate, near start cap. Normals point in direction c + for (int j = 0; j < segments; j++) { + float t = rotation + j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = _ux * std::sin(t) * r + _uy * std::cos(t) * r; + this->vertex_push (vstart+c, vp); + c.renormalize(); + this->vertex_push (c, vn); + this->vertex_push (colStart, vc); + } + + // Intermediate, near end cap. Normals point in direction c + for (int j = 0; j < segments; j++) { + float t = rotation + (float)j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = _ux * std::sin(t) * r + _uy * std::cos(t) * r; + this->vertex_push (vend+c, vp); + c.renormalize(); + this->vertex_push (c, vn); + this->vertex_push (colEnd, vc); + } + + // Bottom cap vertices + for (int j = 0; j < segments; j++) { + float t = rotation + (float)j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = _ux * std::sin(t) * r + _uy * std::cos(t) * r; + this->vertex_push (vend+c, vp); + this->vertex_push (v, vn); + this->vertex_push (colEnd, vc); + } + + // Bottom cap. Push centre vertex as the last vertex. + this->vertex_push (vend, vp); + this->vertex_push (v, vn); + this->vertex_push (colEnd, vc); + + // Number of vertices = segments * 4 + 2. + int nverts = (segments * 4) + 2; + + // After creating vertices, push all the indices. + GLuint capMiddle = _idx; + GLuint capStartIdx = _idx + 1u; + GLuint endMiddle = _idx + static_cast(nverts) - 1u; + GLuint endStartIdx = capStartIdx + (3u * segments); + + // Start cap indices + for (int j = 0; j < segments-1; j++) { + idcs.push_back (capMiddle); + idcs.push_back (capStartIdx + j); + idcs.push_back (capStartIdx + 1 + j); + } + // Last one + idcs.push_back (capMiddle); + idcs.push_back (capStartIdx + segments - 1); + idcs.push_back (capStartIdx); + + // Middle sections + for (int lsection = 0; lsection < 3; ++lsection) { + capStartIdx = _idx + 1 + lsection*segments; + endStartIdx = capStartIdx + segments; + for (int j = 0; j < segments; j++) { + idcs.push_back (capStartIdx + j); + if (j == (segments-1)) { + idcs.push_back (capStartIdx); + } else { + idcs.push_back (capStartIdx + 1 + j); + } + idcs.push_back (endStartIdx + j); + idcs.push_back (endStartIdx + j); + if (j == (segments-1)) { + idcs.push_back (endStartIdx); + } else { + idcs.push_back (endStartIdx + 1 + j); + } + if (j == (segments-1)) { + idcs.push_back (capStartIdx); + } else { + idcs.push_back (capStartIdx + j + 1); + } + } + } + + // bottom cap + for (int j = 0; j < segments-1; j++) { + idcs.push_back (endMiddle); + idcs.push_back (endStartIdx + j); + idcs.push_back (endStartIdx + 1 + j); + } + idcs.push_back (endMiddle); + idcs.push_back (endStartIdx + segments - 1); + idcs.push_back (endStartIdx); + + // Update idx + _idx += nverts; + } // end computeTube with ux/uy vectors for faces + + /*! + * A 'draw an arrow' primitive. This is a 3D, tubular arrow made of a tube and a cone. + * + * \param start Start coordinate of the arrow + * + * \param end End coordinate of the arrow + * + * \param clr The colour for the arrow + * + * \param tube_radius Radius of arrow shaft. If < 0, then set from (end-start).length() + * + * \param arrowhead_prop The proportion of the arrow length that the head should take up + * + * \param cone_radius Radisu of cone that make the arrow head. If < 0, then set from + * tube_radius + * + * \param shapesides How many facets to draw tube/cone with + */ + void computeArrow (const sm::vec& start, const sm::vec& end, + const std::array clr, + float tube_radius = -1.0f, + float arrowhead_prop = -1.0f, + float cone_radius = -1.0f, + const int shapesides = 18) + { + // The right way to draw an arrow. + sm::vec arrow_line = end - start; + float len = arrow_line.length(); + // Unless client code specifies, compute tube radius from length of arrow + if (tube_radius < 0.0f) { tube_radius = len / 40.0f; } + if (arrowhead_prop < 0.0f) { arrowhead_prop = 0.15f; } + if (cone_radius < 0.0f) { cone_radius = 1.75f * tube_radius; } + // We don't draw the full tube + sm::vec cone_start = arrow_line.shorten (len * arrowhead_prop); + cone_start += start; + this->computeTube (start, cone_start, clr, clr, tube_radius, shapesides); + float conelen = (end-cone_start).length(); + if (arrow_line.length() > conelen) { + this->computeCone (cone_start, end, 0.0f, clr, cone_radius, shapesides); + } + } + + /*! + * Create a flared tube from \a start to \a end, with radius \a r at the start and a colour + * which transitions from the colour \a colStart to \a colEnd. The radius of the end is + * determined by the given angle, flare, in radians. + * + * \param idx The index into the 'vertex array' + * \param start The start of the tube + * \param end The end of the tube + * \param colStart The tube starting colour + * \param colEnd The tube's ending colour + * \param r Radius of the tube + * \param segments Number of segments used to render the tube + * \param flare The angle, measured wrt the direction of the tube in radians, by which the + * tube 'flares' + */ + void computeFlaredTube (sm::vec start, sm::vec end, + std::array colStart, std::array colEnd, + float r = 1.0f, int segments = 12, float flare = 0.0f) + { + // Find the length of the tube + sm::vec v = end - start; + float l = v.length(); + // Compute end radius from the length and the flare angle: + float r_add = l * std::tan (std::abs(flare)) * (flare > 0.0f ? 1.0f : -1.0f); + float r_end = r + r_add; + // Now call into the other overload: + this->computeFlaredTube (start, end, colStart, colEnd, r, r_end, segments); + } + + /*! + * Create a flared tube from \a start to \a end, with radius \a r at the start and a colour + * which transitions from the colour \a colStart to \a colEnd. The radius of the end is + * r_end, given as a function argument. + * + * \param start The start of the tube + * \param end The end of the tube + * \param colStart The tube starting colour + * \param colEnd The tube's ending colour + * \param r Radius of the tube's start cap + * \param r_end radius of the end cap + * \param segments Number of segments used to render the tube + */ + void computeFlaredTube (sm::vec start, sm::vec end, + std::array colStart, std::array colEnd, + float r = 1.0f, float r_end = 1.0f, int segments = 12) + { + // The vector from start to end defines a vector and a plane. Find a + // 'circle' of points in that plane. + sm::vec vstart = start; + sm::vec vend = end; + sm::vec v = vend - vstart; + v.renormalize(); + + // circle in a plane defined by a point (v0 = vstart or vend) and a normal + // (v) can be found: Choose random vector vr. A vector inplane = vr ^ v. The + // unit in-plane vector is inplane.normalise. Can now use that vector in the + // plan to define a point on the circle. Note that this starting point on + // the circle is at a random position, which means that this version of + // computeTube is useful for tubes that have quite a few segments. + sm::vec rand_vec; + rand_vec.randomize(); + sm::vec inplane = rand_vec.cross(v); + inplane.renormalize(); + + // Now use parameterization of circle inplane = p1-x1 and + // c1(t) = ( (p1-x1).normalized std::sin(t) + v.normalized cross (p1-x1).normalized * std::cos(t) ) + // c1(t) = ( inplane std::sin(t) + v * inplane * std::cos(t) + sm::vec v_x_inplane = v.cross(inplane); + + // Push the central point of the start cap - this is at location vstart + this->vertex_push (vstart, this->vertexPositions); + this->vertex_push (-v, this->vertexNormals); + this->vertex_push (colStart, this->vertexColors); + + // Start cap vertices. Draw as a triangle fan, but record indices so that we + // only need a single call to glDrawElements. + for (int j = 0; j < segments; j++) { + // t is the angle of the segment + float t = j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = inplane * std::sin(t) * r + v_x_inplane * std::cos(t) * r; + this->vertex_push (vstart+c, this->vertexPositions); + this->vertex_push (-v, this->vertexNormals); + this->vertex_push (colStart, this->vertexColors); + } + + // Intermediate, near start cap. Normals point in direction c + for (int j = 0; j < segments; j++) { + float t = j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = inplane * std::sin(t) * r + v_x_inplane * std::cos(t) * r; + this->vertex_push (vstart+c, this->vertexPositions); + c.renormalize(); + this->vertex_push (c, this->vertexNormals); + this->vertex_push (colStart, this->vertexColors); + } + + // Intermediate, near end cap. Normals point in direction c + for (int j = 0; j < segments; j++) { + float t = (float)j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = inplane * std::sin(t) * r_end + v_x_inplane * std::cos(t) * r_end; + this->vertex_push (vend+c, this->vertexPositions); + c.renormalize(); + this->vertex_push (c, this->vertexNormals); + this->vertex_push (colEnd, this->vertexColors); + } + + // Bottom cap vertices + for (int j = 0; j < segments; j++) { + float t = (float)j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = inplane * std::sin(t) * r_end + v_x_inplane * std::cos(t) * r_end; + this->vertex_push (vend+c, this->vertexPositions); + this->vertex_push (v, this->vertexNormals); + this->vertex_push (colEnd, this->vertexColors); + } + + // Bottom cap. Push centre vertex as the last vertex. + this->vertex_push (vend, this->vertexPositions); + this->vertex_push (v, this->vertexNormals); + this->vertex_push (colEnd, this->vertexColors); + + // Note: number of vertices = segments * 4 + 2. + int nverts = (segments * 4) + 2; + + // After creating vertices, push all the indices. + GLuint capMiddle = this->idx; + GLuint capStartIdx = this->idx + 1u; + GLuint endMiddle = this->idx + static_cast(nverts) - 1u; + GLuint endStartIdx = capStartIdx + (3u * segments); + + // Start cap + for (int j = 0; j < segments-1; j++) { + this->indices.push_back (capMiddle); + this->indices.push_back (capStartIdx + j); + this->indices.push_back (capStartIdx + 1 + j); + } + // Last one + this->indices.push_back (capMiddle); + this->indices.push_back (capStartIdx + segments - 1); + this->indices.push_back (capStartIdx); + + // Middle sections + for (int lsection = 0; lsection < 3; ++lsection) { + capStartIdx = this->idx + 1 + lsection*segments; + endStartIdx = capStartIdx + segments; + // This does sides between start and end. I want to do this three times. + for (int j = 0; j < segments; j++) { + // Triangle 1 + this->indices.push_back (capStartIdx + j); + if (j == (segments-1)) { + this->indices.push_back (capStartIdx); + } else { + this->indices.push_back (capStartIdx + 1 + j); + } + this->indices.push_back (endStartIdx + j); + // Triangle 2 + this->indices.push_back (endStartIdx + j); + if (j == (segments-1)) { + this->indices.push_back (endStartIdx); + } else { + this->indices.push_back (endStartIdx + 1 + j); + } + if (j == (segments-1)) { + this->indices.push_back (capStartIdx); + } else { + this->indices.push_back (capStartIdx + j + 1); + } + } + } + + // Bottom cap + for (int j = 0; j < segments-1; j++) { + this->indices.push_back (endMiddle); + this->indices.push_back (endStartIdx + j); + this->indices.push_back (endStartIdx + 1 + j); + } + // Last one + this->indices.push_back (endMiddle); + this->indices.push_back (endStartIdx + segments - 1); + this->indices.push_back (endStartIdx); + + // Update idx + this->idx += nverts; + } // end computeFlaredTube with randomly initialized end vertices + + /*! + * Create an open (no end caps) flared tube from \a start to \a end, with radius + * \a r at the start and a colour which transitions from the colour \a colStart + * to \a colEnd. The radius of the end is r_end, given as a function argument. + * + * This has a normal vector for the start and end of the tube, so that the + * circles can be angled. + * + * \param start The start of the tube + * \param end The end of the tube + * \param colStart The tube starting colour + * \param colEnd The tube's ending colour + * \param n_start The normal of the start 'face' + * \param n_end The normal of the end 'face' + * + * \param z_start A vector pointing to the first vertex on the tube. allows + * orientation of tube faces for connected tubes (which is what this primitive + * is all about) + * + * \param r Radius of the tube's start circle + * \param r_end radius of the end circle + * \param segments Number of segments used to render the tube + */ + void computeOpenFlaredTube (sm::vec start, sm::vec end, + sm::vec n_start, sm::vec n_end, + std::array colStart, std::array colEnd, + float r = 1.0f, float r_end = 1.0f, int segments = 12) + { + // The vector from start to end defines a vector and a plane. Find a + // 'circle' of points in that plane. + sm::vec vstart = start; + sm::vec vend = end; + sm::vec v = vend - vstart; + v.renormalize(); + + // Two rotations about our face normals + sm::quaternion rotn_start (n_start, sm::mathconst::pi_over_2); + sm::quaternion rotn_end (-n_end, sm::mathconst::pi_over_2); + + sm::vec inplane = v.cross (n_start); + // The above is no good if n_start and v are colinear. In that case choose random inplane: + if (inplane.length() < std::numeric_limits::epsilon()) { + sm::vec rand_vec; + rand_vec.randomize(); + inplane = rand_vec.cross(v); + } + inplane.renormalize(); + + // inplane defines a plane, n_start defines a plane. Our first point is the + // intersection of the two planes and the circle of the end. + sm::vec v_x_inplane = n_start.cross (inplane);// rotn_start * inplane; + v_x_inplane.renormalize(); + + // If r == r_end we want a circular cross section tube (and not an elliptical cross section). + float r_mod = r / v_x_inplane.cross (v).length(); + + // Start ring of vertices. Normals point in direction c + // Now use parameterization of circle inplane = p1-x1 and + // c1(t) = ( (p1-x1).normalized std::sin(t) + v.normalized cross (p1-x1).normalized * std::cos(t) ) + // c1(t) = ( inplane std::sin(t) + v * inplane * std::cos(t) + for (int j = 0; j < segments; j++) { + float t = j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = inplane * std::sin(t) * r + v_x_inplane * std::cos(t) * r_mod; + this->vertex_push (vstart+c, this->vertexPositions); + c.renormalize(); + this->vertex_push (c, this->vertexNormals); + this->vertex_push (colStart, this->vertexColors); + } + + // end ring of vertices. Normals point in direction c + v_x_inplane = inplane.cross (n_end); + v_x_inplane.renormalize(); + r_mod = r_end / v_x_inplane.cross (v).length(); + + for (int j = 0; j < segments; j++) { + float t = (float)j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = inplane * std::sin(t) * r_end + v_x_inplane * std::cos(t) * r_mod; + this->vertex_push (vend+c, this->vertexPositions); + c.renormalize(); + this->vertex_push (c, this->vertexNormals); + this->vertex_push (colEnd, this->vertexColors); + } + + // Number of vertices + int nverts = (segments * 2); + + // After creating vertices, push all the indices. + GLuint sIdx = this->idx; + GLuint eIdx = sIdx + segments; + // This does sides between start and end + for (int j = 0; j < segments; j++) { + // Triangle 1 + this->indices.push_back (sIdx + j); + if (j == (segments-1)) { + this->indices.push_back (sIdx); + } else { + this->indices.push_back (sIdx + 1 + j); + } + this->indices.push_back (eIdx + j); + // Triangle 2 + this->indices.push_back (eIdx + j); + if (j == (segments-1)) { + this->indices.push_back (eIdx); + } else { + this->indices.push_back (eIdx + 1 + j); + } + if (j == (segments-1)) { + this->indices.push_back (sIdx); + } else { + this->indices.push_back (sIdx + j + 1); + } + } + + // Update idx + this->idx += nverts; + } // end computeOpenFlaredTube + + // An open, but un-flared tube with no end caps + void computeOpenTube (sm::vec start, sm::vec end, + sm::vec n_start, sm::vec n_end, + std::array colStart, std::array colEnd, + float r = 1.0f, int segments = 12) + { + this->computeOpenFlaredTube (start, end, n_start, n_end, colStart, colEnd, r, r, segments); + } + + + //! Compute a Quad from 4 arbitrary corners which must be ordered clockwise around the quad. + void computeFlatQuad (sm::vec c1, sm::vec c2, + sm::vec c3, sm::vec c4, + std::array col) + { + // v is the face normal + sm::vec u1 = c1-c2; + sm::vec u2 = c2-c3; + sm::vec v = u2.cross(u1); + v.renormalize(); + + // Push corner vertices + size_t vpsz = this->vertexPositions.size(); + this->vertexPositions.resize (vpsz + 12); + for (unsigned int i = 0; i < 3u; ++i) { this->vertexPositions[vpsz++] = c1[i]; } + for (unsigned int i = 0; i < 3u; ++i) { this->vertexPositions[vpsz++] = c2[i]; } + for (unsigned int i = 0; i < 3u; ++i) { this->vertexPositions[vpsz++] = c3[i]; } + for (unsigned int i = 0; i < 3u; ++i) { this->vertexPositions[vpsz++] = c4[i]; } + + // Colours/normals + size_t vcsz = this->vertexColors.size(); + size_t vnsz = this->vertexNormals.size(); + this->vertexColors.resize (vcsz + 12); + this->vertexNormals.resize (vnsz + 12); + for (unsigned int i = 0; i < 4u; ++i) { + for (unsigned int j = 0; j < 3u; ++j) { + this->vertexColors[vcsz++] = col[j]; + this->vertexNormals[vnsz++] = v[j]; + } + } + + size_t i0 = this->indices.size(); + this->indices.resize (i0 + 6, 0); + this->indices[i0++] = this->idx; + this->indices[i0++] = this->idx + 2; + this->indices[i0++] = this->idx + 1; + this->indices[i0++] = this->idx; + this->indices[i0++] = this->idx + 3; + this->indices[i0++] = this->idx + 2; + + this->idx += 4; + } + + /*! + * Compute a tube. This version requires unit vectors for orientation of the + * tube end faces/vertices (useful for graph markers). The other version uses a + * randomly chosen vector to do this. + * + * Create a tube from \a start to \a end, with radius \a r and a colour which + * transitions from the colour \a colStart to \a colEnd. + * + * \param idx The index into the 'vertex array' + * \param vstart The centre of the polygon + * \param _ux a vector in the x axis direction for the end face + * \param _uy a vector in the y axis direction + * \param col The polygon colour + * \param r Radius of the tube + * \param segments Number of segments used to render the tube + * \param rotation A rotation in the ux/uy plane to orient the vertices of the + * tube. Useful if this is to be a short tube used as a graph marker. + */ + void computeFlatPoly (sm::vec vstart, + sm::vec _ux, sm::vec _uy, + std::array col, + float r = 1.0f, int segments = 12, float rotation = 0.0f) + { + // v is a face normal + sm::vec v = _uy.cross(_ux); + v.renormalize(); + + // Push the central point of the start cap - this is at location vstart + this->vertex_push (vstart, this->vertexPositions); + this->vertex_push (-v, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + // Polygon vertices (a triangle fan) + for (int j = 0; j < segments; j++) { + // t is the angle of the segment + float t = rotation + j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = _ux * std::sin(t) * r + _uy * std::cos(t) * r; + this->vertex_push (vstart+c, this->vertexPositions); + this->vertex_push (-v, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + } + + // Number of vertices + int nverts = segments + 1; + + // After creating vertices, push all the indices. + GLuint capMiddle = this->idx; + GLuint capStartIdx = this->idx + 1; + + // Start cap indices + for (int j = 0; j < segments-1; j++) { + this->indices.push_back (capMiddle); + this->indices.push_back (capStartIdx + j); + this->indices.push_back (capStartIdx + 1 + j); + } + // Last one + this->indices.push_back (capMiddle); + this->indices.push_back (capStartIdx + segments - 1); + this->indices.push_back (capStartIdx); + + // Update idx + this->idx += nverts; + } // end computeFlatPloy with ux/uy vectors for faces + + /*! + * Make a ring of radius r, comprised of flat segments + * + * \param ro position of the centre of the ring + * \param rc The ring colour. + * \param r Radius of the ring + * \param t Thickness of the ring + * \param segments Number of tube segments used to render the ring + */ + void computeRing (sm::vec ro, std::array rc, float r = 1.0f, + float t = 0.1f, int segments = 12) + { + float r_in = r - (t * 0.5f); + float r_out = r + (t * 0.5f); + this->computeRingInOut (ro, rc, r_in, r_out, segments); + } + + /*! + * Make a ring of radius r, comprised of flat segments, specifying inner and outer radii + * + * \param ro position of the centre of the ring + * \param rc The ring colour. + * \param r_in Inner radius of the ring + * \param r_out Outer radius of the ring + * \param segments Number of tube segments used to render the ring + */ + void computeRingInOut (sm::vec ro, std::array rc, + float r_in = 1.0f, float r_out = 2.0f, int segments = 12) + { + for (int j = 0; j < segments; j++) { + float segment = sm::mathconst::two_pi * static_cast(j) / segments; + // x and y of inner point + float xin = r_in * std::cos (segment); + float yin = r_in * std::sin (segment); + float xout = r_out * std::cos (segment); + float yout = r_out * std::sin (segment); + int segjnext = (j + 1) % segments; + float segnext = sm::mathconst::two_pi * static_cast(segjnext) / segments; + float xin_n = r_in * std::cos (segnext); + float yin_n = r_in * std::sin (segnext); + float xout_n = r_out * std::cos (segnext); + float yout_n = r_out * std::sin (segnext); + + // Now draw a quad + sm::vec c4 = { xin, yin, 0.0f }; + sm::vec c3 = { xout, yout, 0.0f }; + sm::vec c2 = { xout_n, yout_n, 0.0f }; + sm::vec c1 = { xin_n, yin_n, 0.0f }; + this->computeFlatQuad (ro + c1, ro + c2, ro + c3, ro + c4, rc); + } + } + + /*! + * Sphere, geodesic polygon version. + * + * This function creates an object with exactly one OpenGL vertex per 'geometric + * vertex of the polyhedron'. That means that colouring this object must be + * achieved by colouring the vertices and faces cannot be coloured + * distinctly. Pass in a single colour for the initial object. To recolour, + * modify the content of vertexColors. + * + * \tparam F The type used for the polyhedron computation. Use float or double. + * + * \param so The sphere offset. Where to place this sphere... + * \param sc The sphere colour. + * \param r Radius of the sphere + * \param iterations how many iterations of the geodesic polygon algo to go + * through. Determines faces: + * + * For 0 iterations, get a geodesic with 20 faces *0 + * For 1 iterations, get a geodesic with 80 faces + * For 2 iterations, get a geodesic with 320 faces *1 + * For 3 iterations, get a geodesic with 1280 faces *2 + * For 4 iterations, get a geodesic with 5120 faces *3 + * For 5 iterations, get a geodesic with 20480 faces *4 + * For 6 iterations, get a geodesic with 81920 faces + * For 7 iterations, get a geodesic with 327680 faces + * For 8 iterations, get a geodesic with 1310720 faces + * For 9 iterations, get a geodesic with 5242880 faces + * + * *0: You'll get an icosahedron + * *1: decent graphical results + * *2: excellent graphical results + * *3: You can *just about* see a difference between 4 iterations and 3, but not + * between 4 and 5. + * *4: The iterations limit if F is float (you'll get a runtime error 'vertices + * has wrong size' for iterations>5) + * + * \return The number of vertices in the generated geodesic sphere + */ + template + int computeSphereGeo (sm::vec so, std::array sc, float r = 1.0f, int iterations = 2) + { + if (iterations < 0) { throw std::runtime_error ("computeSphereGeo: iterations must be positive"); } + // test if type F is float + if constexpr (std::is_same, float>::value == true) { + if (iterations > 5) { + throw std::runtime_error ("computeSphereGeo: For iterations > 5, F needs to be double precision"); + } + } else { + if (iterations > 10) { + throw std::runtime_error ("computeSphereGeo: This is an abitrary iterations limit (10 gives 20971520 faces)"); + } + } + // Note that we need double precision to compute higher iterations of the geodesic (iterations > 5) + sm::geometry::icosahedral_geodesic geo = sm::geometry::make_icosahedral_geodesic (iterations); + + // Now essentially copy geo into vertex buffers + for (auto v : geo.poly.vertices) { + this->vertex_push (v.as_float() * r + so, this->vertexPositions); + this->vertex_push (v.as_float(), this->vertexNormals); + this->vertex_push (sc, this->vertexColors); + } + for (auto f : geo.poly.faces) { + this->indices.push_back (this->idx + f[0]); + this->indices.push_back (this->idx + f[1]); + this->indices.push_back (this->idx + f[2]); + } + // idx is the *vertex index* and should be incremented by the number of vertices in the polyhedron + int n_verts = static_cast(geo.poly.vertices.size()); + this->idx += n_verts; + + return n_verts; + } + + /*! + * Sphere, geodesic polygon version with coloured faces + * + * To colour the faces of this polyhedron, update this->vertexColors (for an + * example see mplot::GeodesicVisual). To make faces distinctly colourizable, we + * have to generate 3 OpenGL vertices for each of the geometric vertices in the + * polyhedron. + * + * \tparam F The type used for the polyhedron computation. Use float or double. + * + * \param so The sphere offset. Where to place this sphere... + * \param sc The default colour + * \param r Radius of the sphere + * \param iterations how many iterations of the geodesic polygon algo to go + * through. Determines number of faces + */ + template + int computeSphereGeoFaces (sm::vec so, std::array sc, float r = 1.0f, int iterations = 2) + { + if (iterations < 0) { throw std::runtime_error ("computeSphereGeo: iterations must be positive"); } + // test if type F is float + if constexpr (std::is_same, float>::value == true) { + if (iterations > 5) { + throw std::runtime_error ("computeSphereGeo: For iterations > 5, F needs to be double precision"); + } + } else { + if (iterations > 10) { + throw std::runtime_error ("computeSphereGeo: This is an abitrary iterations limit (10 gives 20971520 faces)"); + } + } + // Note that we need double precision to compute higher iterations of the geodesic (iterations > 5) + sm::geometry::icosahedral_geodesic geo = sm::geometry::make_icosahedral_geodesic (iterations); + int n_faces = static_cast(geo.poly.faces.size()); + + for (int i = 0; i < n_faces; ++i) { // For each face in the geodesic... + sm::vec norm = { F{0}, F{0}, F{0} }; + for (auto vtx : geo.poly.faces[i]) { // For each vertex in face... + norm += geo.poly.vertices[vtx]; // Add to the face norm + this->vertex_push (geo.poly.vertices[vtx].as_float() * r + so, this->vertexPositions); + } + sm::vec nf = (norm / F{3}).as_float(); + for (int j = 0; j < 3; ++j) { // Faces all have size 3 + this->vertex_push (nf, this->vertexNormals); + this->vertex_push (sc, this->vertexColors); // A default colour + this->indices.push_back (this->idx + (3 * i) + j); // indices is vertex index + } + } + // An index for each vertex of each face. + this->idx += 3 * n_faces; + + return n_faces; + } + + //! Fast computeSphereGeo, which uses constexpr make_icosahedral_geodesic. The + //! resulting vertices and faces are NOT in any kind of order, but ok for + //! plotting, e.g. scatter graph spheres. + template + int computeSphereGeoFast (sm::vec so, std::array sc, float r = 1.0f) + { + // test if type F is float + if constexpr (std::is_same, float>::value == true) { + static_assert (iterations <= 5, "computeSphereGeoFast: For iterations > 5, F needs to be double precision"); + } else { + static_assert (iterations <= 10, "computeSphereGeoFast: This is an abitrary iterations limit (10 gives 20971520 faces)"); + } + // Note that we need double precision to compute higher iterations of the geodesic (iterations > 5) + constexpr sm::geometry_ce::icosahedral_geodesic geo = sm::geometry_ce::make_icosahedral_geodesic(); + + // Now essentially copy geo into vertex buffers + for (auto v : geo.poly.vertices) { + this->vertex_push (v.as_float() * r + so, this->vertexPositions); + this->vertex_push (v.as_float(), this->vertexNormals); + this->vertex_push (sc, this->vertexColors); + } + for (auto f : geo.poly.faces) { + this->indices.push_back (this->idx + f[0]); + this->indices.push_back (this->idx + f[1]); + this->indices.push_back (this->idx + f[2]); + } + // idx is the *vertex index* and should be incremented by the number of vertices in the polyhedron + int n_verts = static_cast(geo.poly.vertices.size()); + this->idx += n_verts; + + return n_verts; + } + + /*! + * Sphere, 1 colour version. + * + * Code for creating a sphere as part of this model. I'll use a sphere at the centre of the arrows. + * + * \param so The sphere offset. Where to place this sphere... + * \param sc The sphere colour. + * \param r Radius of the sphere + * \param rings Number of rings used to render the sphere + * \param segments Number of segments used to render the sphere + * + * Number of faces should be (2 + rings) * segments + */ + void computeSphere (sm::vec so, std::array sc, + float r = 1.0f, int rings = 10, int segments = 12) + { + // First cap, draw as a triangle fan, but record indices so that + // we only need a single call to glDrawElements. + float rings0 = -sm::mathconst::pi_over_2; + float _z0 = std::sin(rings0); + float z0 = r * _z0; + float r0 = std::cos(rings0); + float rings1 = sm::mathconst::pi * (-0.5f + 1.0f / rings); + float _z1 = std::sin(rings1); + float z1 = r * _z1; + float r1 = std::cos(rings1); + // Push the central point + this->vertex_push (so[0]+0.0f, so[1]+0.0f, so[2]+z0, this->vertexPositions); + this->vertex_push (0.0f, 0.0f, -1.0f, this->vertexNormals); + this->vertex_push (sc, this->vertexColors); + + GLuint capMiddle = this->idx++; + GLuint ringStartIdx = this->idx; + GLuint lastRingStartIdx = this->idx; + + bool firstseg = true; + for (int j = 0; j < segments; j++) { + float segment = sm::mathconst::two_pi * static_cast(j) / segments; + float x = std::cos(segment); + float y = std::sin(segment); + + float _x1 = x*r1; + float x1 = _x1*r; + float _y1 = y*r1; + float y1 = _y1*r; + + this->vertex_push (so[0]+x1, so[1]+y1, so[2]+z1, this->vertexPositions); + this->vertex_push (_x1, _y1, _z1, this->vertexNormals); + this->vertex_push (sc, this->vertexColors); + + if (!firstseg) { + this->indices.push_back (capMiddle); + this->indices.push_back (this->idx-1); + this->indices.push_back (this->idx++); + } else { + this->idx++; + firstseg = false; + } + } + this->indices.push_back (capMiddle); + this->indices.push_back (this->idx-1); + this->indices.push_back (capMiddle+1); + + // Now add the triangles around the rings + for (int i = 2; i < rings; i++) { + + rings0 = sm::mathconst::pi * (-0.5f + static_cast(i) / rings); + _z0 = std::sin(rings0); + z0 = r * _z0; + r0 = std::cos(rings0); + + for (int j = 0; j < segments; j++) { + + // "current" segment + float segment = sm::mathconst::two_pi * static_cast(j) / segments; + float x = std::cos(segment); + float y = std::sin(segment); + + // One vertex per segment + float _x0 = x*r0; + float x0 = _x0*r; + float _y0 = y*r0; + float y0 = _y0*r; + + // NB: Only add ONE vertex per segment. ALREADY have the first ring! + this->vertex_push (so[0]+x0, so[1]+y0, so[2]+z0, this->vertexPositions); + // The vertex normal of a vertex that makes up a sphere is + // just a normal vector in the direction of the vertex. + this->vertex_push (_x0, _y0, _z0, this->vertexNormals); + this->vertex_push (sc, this->vertexColors); + + if (j == segments - 1) { + // Last vertex is back to the start + this->indices.push_back (ringStartIdx++); + this->indices.push_back (this->idx); + this->indices.push_back (lastRingStartIdx); + this->indices.push_back (lastRingStartIdx); + this->indices.push_back (this->idx++); + this->indices.push_back (lastRingStartIdx+segments); + } else { + this->indices.push_back (ringStartIdx++); + this->indices.push_back (this->idx); + this->indices.push_back (ringStartIdx); + this->indices.push_back (ringStartIdx); + this->indices.push_back (this->idx++); + this->indices.push_back (this->idx); + } + } + lastRingStartIdx += segments; + } + + // bottom cap + rings0 = sm::mathconst::pi_over_2; + _z0 = std::sin(rings0); + z0 = r * _z0; + r0 = std::cos(rings0); + // Push the central point of the bottom cap + this->vertex_push (so[0]+0.0f, so[1]+0.0f, so[2]+z0, this->vertexPositions); + this->vertex_push (0.0f, 0.0f, 1.0f, this->vertexNormals); + this->vertex_push (sc, this->vertexColors); + capMiddle = this->idx++; + firstseg = true; + // No more vertices to push, just do the indices for the bottom cap + ringStartIdx = lastRingStartIdx; + for (int j = 0; j < segments; j++) { + if (j != segments - 1) { + this->indices.push_back (capMiddle); + this->indices.push_back (ringStartIdx++); + this->indices.push_back (ringStartIdx); + } else { + // Last segment + this->indices.push_back (capMiddle); + this->indices.push_back (ringStartIdx); + this->indices.push_back (lastRingStartIdx); + } + } + } // end of sphere calculation + + /*! + * Sphere, two colour version. + * + * Code for creating a sphere as part of this model. I'll use a sphere at the + * centre of the arrows. + * + * \param so The sphere offset. Where to place this sphere... + * \param sc The sphere colour. + * \param sc2 The sphere's second colour - used for cap and first ring + * \param r Radius of the sphere + * \param rings Number of rings used to render the sphere + * \param segments Number of segments used to render the sphere + */ + void computeSphere (sm::vec so, std::array sc, std::array sc2, + float r = 1.0f, int rings = 10, int segments = 12) + { + // First cap, draw as a triangle fan, but record indices so that + // we only need a single call to glDrawElements. + float rings0 = -sm::mathconst::pi_over_2; + float _z0 = std::sin(rings0); + float z0 = r * _z0; + float r0 = std::cos(rings0); + float rings1 = sm::mathconst::pi * (-0.5f + 1.0f / rings); + float _z1 = std::sin(rings1); + float z1 = r * _z1; + float r1 = std::cos(rings1); + // Push the central point + this->vertex_push (so[0]+0.0f, so[1]+0.0f, so[2]+z0, this->vertexPositions); + this->vertex_push (0.0f, 0.0f, -1.0f, this->vertexNormals); + this->vertex_push (sc2, this->vertexColors); + + GLuint capMiddle = this->idx++; + GLuint ringStartIdx = this->idx; + GLuint lastRingStartIdx = this->idx; + + bool firstseg = true; + for (int j = 0; j < segments; j++) { + float segment = sm::mathconst::two_pi * static_cast(j) / segments; + float x = std::cos(segment); + float y = std::sin(segment); + + float _x1 = x*r1; + float x1 = _x1*r; + float _y1 = y*r1; + float y1 = _y1*r; + + this->vertex_push (so[0]+x1, so[1]+y1, so[2]+z1, this->vertexPositions); + this->vertex_push (_x1, _y1, _z1, this->vertexNormals); + this->vertex_push (sc2, this->vertexColors); + + if (!firstseg) { + this->indices.push_back (capMiddle); + this->indices.push_back (this->idx-1); + this->indices.push_back (this->idx++); + } else { + this->idx++; + firstseg = false; + } + } + this->indices.push_back (capMiddle); + this->indices.push_back (this->idx-1); + this->indices.push_back (capMiddle+1); + + // Now add the triangles around the rings + for (int i = 2; i < rings; i++) { + + rings0 = sm::mathconst::pi * (-0.5f + static_cast(i) / rings); + _z0 = std::sin(rings0); + z0 = r * _z0; + r0 = std::cos(rings0); + + for (int j = 0; j < segments; j++) { + + // "current" segment + float segment = sm::mathconst::two_pi * static_cast(j) / segments; + float x = std::cos(segment); + float y = std::sin(segment); + + // One vertex per segment + float _x0 = x*r0; + float x0 = _x0*r; + float _y0 = y*r0; + float y0 = _y0*r; + + // NB: Only add ONE vertex per segment. ALREADY have the first ring! + this->vertex_push (so[0]+x0, so[1]+y0, so[2]+z0, this->vertexPositions); + // The vertex normal of a vertex that makes up a sphere is + // just a normal vector in the direction of the vertex. + this->vertex_push (_x0, _y0, _z0, this->vertexNormals); + if (i == 2 || i > (rings-2)) { + this->vertex_push (sc2, this->vertexColors); + } else { + this->vertex_push (sc, this->vertexColors); + } + if (j == segments - 1) { + // Last vertex is back to the start + this->indices.push_back (ringStartIdx++); + this->indices.push_back (this->idx); + this->indices.push_back (lastRingStartIdx); + this->indices.push_back (lastRingStartIdx); + this->indices.push_back (this->idx++); + this->indices.push_back (lastRingStartIdx+segments); + } else { + this->indices.push_back (ringStartIdx++); + this->indices.push_back (this->idx); + this->indices.push_back (ringStartIdx); + this->indices.push_back (ringStartIdx); + this->indices.push_back (this->idx++); + this->indices.push_back (this->idx); + } + } + lastRingStartIdx += segments; + } + + // bottom cap + rings0 = sm::mathconst::pi_over_2; + _z0 = std::sin(rings0); + z0 = r * _z0; + r0 = std::cos(rings0); + // Push the central point of the bottom cap + this->vertex_push (so[0]+0.0f, so[1]+0.0f, so[2]+z0, this->vertexPositions); + this->vertex_push (0.0f, 0.0f, 1.0f, this->vertexNormals); + this->vertex_push (sc2, this->vertexColors); + capMiddle = this->idx++; + firstseg = true; + // No more vertices to push, just do the indices for the bottom cap + ringStartIdx = lastRingStartIdx; + for (int j = 0; j < segments; j++) { + if (j != segments - 1) { + this->indices.push_back (capMiddle); + this->indices.push_back (ringStartIdx++); + this->indices.push_back (ringStartIdx); + } else { + // Last segment + this->indices.push_back (capMiddle); + this->indices.push_back (ringStartIdx); + this->indices.push_back (lastRingStartIdx); + } + } + } + + /*! + * Compute an ellipsoid surface of the form x*x/a*a + y*y/b*b + z*z/c*c = 1 + * + * so is the offset position for the ellipsoid + * + * sc is the colour at one end of the z axis + * + * sc2 is the colour at the other end + * + * abc are the three ellipsoid parameters + * + * rings is the number of rings along the z axis + * + * segments is the number of segments in each ring along the z axis + * + * tr transform matrix to apply to each point in the ellipse (applied before so is applied + * as a transform) + */ + void computeEllipsoid (sm::vec so, + std::array sc, + std::array sc2, + sm::vec abc, + int rings = 10, int segments = 12, + sm::mat tr = sm::mat{}) + { + // We have two angular parameters t and t2. t in range 0-2pi and t2 in range 0-pi. t + // gives the 'xy' ellipse; t2 gives the change in size of the xy ellipse as the z axis + // is traversed. + float t = 0.0f; + float t2 = 0.0f; + // used computing normals + sm::vec two_over_abcsq = 2.0f / abc.sq(); + // Holding the coordinates of each point on the ellipsoid as we compute it + sm::vec p = {}; + // The normal vector + sm::vec n = {}; + + // sm::vec versions of the colours + sm::vec _sc = {}; + _sc.set_from (sc); + sm::vec _sc2 = {}; + _sc2.set_from (sc2); + + // Push the central point + p = { 0, 0, abc[2] }; + this->vertex_push (so + (tr * p).less_one_dim(), this->vertexPositions); + n = { 0, 0, 1 }; + this->vertex_push (n, this->vertexNormals); + this->vertex_push (_sc, this->vertexColors); + + GLuint capMiddle = this->idx++; + GLuint ringStartIdx = this->idx; + GLuint lastRingStartIdx = this->idx; + + t2 = sm::mathconst::pi / rings; + p[2] = abc[2] * std::cos(t2); + + bool firstseg = true; + for (int j = 0; j < segments; j++) { + + t = sm::mathconst::two_pi * static_cast(j) / segments; + p[0] = abc[0] * std::cos(t) * std::sin(t2); + p[1] = abc[1] * std::sin(t) * std::sin(t2); + + sm::vec<> pp = (tr * p).less_one_dim(); + this->vertex_push (so + pp, this->vertexPositions); + + n = (tr * (p * two_over_abcsq)).less_one_dim(); + n.renormalize(); + this->vertex_push (n, this->vertexNormals); + + sm::vec sc_ring = _sc * (1.0f - 1.0f / rings) + _sc2 * 1.0f / rings; + this->vertex_push (sc_ring, this->vertexColors); + + if (!firstseg) { + this->indices.push_back (capMiddle); + this->indices.push_back (this->idx-1); + this->indices.push_back (this->idx++); + } else { + this->idx++; + firstseg = false; + } + } + this->indices.push_back (capMiddle); + this->indices.push_back (this->idx-1); + this->indices.push_back (capMiddle+1); + + // Now add the triangles around the rings + for (int i = 2; i < rings; i++) { + + t2 = sm::mathconst::pi * (static_cast(i) / rings); + p[2] = abc[2] * std::cos(t2); + + sm::vec sc_ring = _sc * (1.0f - static_cast(i) / rings) + _sc2 * static_cast(i) / rings; + + for (int j = 0; j < segments; j++) { + + // "current" segment + t = sm::mathconst::two_pi * static_cast(j) / segments; + p[0] = abc[0] * std::cos(t) * std::sin(t2); + p[1] = abc[1] * std::sin(t) * std::sin(t2); + + // NB: Only add ONE vertex per segment. ALREADY have the first ring! + sm::vec<> pp = (tr * p).less_one_dim(); + this->vertex_push (so + pp, this->vertexPositions); + // The vertex normal of a vertex that makes up a sphere is + // just a normal vector in the direction of the vertex. + n = (tr * (p * two_over_abcsq)).less_one_dim(); + n.renormalize(); + this->vertex_push (n, this->vertexNormals); + + this->vertex_push (sc_ring, this->vertexColors); + + if (j == segments - 1) { + // Last vertex is back to the start + this->indices.push_back (ringStartIdx++); + this->indices.push_back (this->idx); + this->indices.push_back (lastRingStartIdx); + this->indices.push_back (lastRingStartIdx); + this->indices.push_back (this->idx++); + this->indices.push_back (lastRingStartIdx+segments); + } else { + this->indices.push_back (ringStartIdx++); + this->indices.push_back (this->idx); + this->indices.push_back (ringStartIdx); + this->indices.push_back (ringStartIdx); + this->indices.push_back (this->idx++); + this->indices.push_back (this->idx); + } + } + lastRingStartIdx += segments; + } + + // bottom cap + + // Push the central point of the bottom cap + p = { 0, 0, -abc[2] }; + this->vertex_push (so + (tr * p).less_one_dim(), this->vertexPositions); + n = { 0, 0, -1 }; + this->vertex_push (n, this->vertexNormals); + this->vertex_push (_sc2, this->vertexColors); + capMiddle = this->idx++; + firstseg = true; + // No more vertices to push, just do the indices for the bottom cap + ringStartIdx = lastRingStartIdx; + for (int j = 0; j < segments; j++) { + if (j != segments - 1) { + this->indices.push_back (capMiddle); + this->indices.push_back (ringStartIdx++); + this->indices.push_back (ringStartIdx); + } else { + // Last segment + this->indices.push_back (capMiddle); + this->indices.push_back (ringStartIdx); + this->indices.push_back (lastRingStartIdx); + } + } + } + + /*! + * Compute vertices for an icosahedron. + */ + void computeIcosahedron (sm::vec centre, + std::array, 20> face_colours, + float r = 1.0f) // radius or side length? + { + sm::geometry::polyhedron ico = sm::geometry::icosahedron(); + + for (int j = 0; j < 20; ++j) { + // Compute the face normal + sm::vec norml = (ico.vertices[ico.faces[j][0]] + ico.vertices[ico.faces[j][1]] + ico.vertices[ico.faces[j][2]])/3.0f; + this->vertex_push (centre + (ico.vertices[ico.faces[j][0]] * r), this->vertexPositions); + this->vertex_push (centre + (ico.vertices[ico.faces[j][1]] * r), this->vertexPositions); + this->vertex_push (centre + (ico.vertices[ico.faces[j][2]] * r), this->vertexPositions); + for (int i = 0; i < 3; ++i) { + this->vertex_push (norml, this->vertexNormals); + this->vertex_push (face_colours[j], this->vertexColors); + } + // Indices... + this->indices.push_back (this->idx); + this->indices.push_back (this->idx+1); + this->indices.push_back (this->idx+2); + this->idx += 3; + } + } + + /*! + * Create a cone. + * + * \param centre The centre of the cone - would be the end of the line + * + * \param tip The tip of the cone + * + * \param ringoffset Move the ring forwards or backwards along the vector from + * \a centre to \a tip. This is positive or negative proportion of tip - centre. + * + * \param col The cone colour + * + * \param r Radius of the ring + * + * \param segments Number of segments used to render the tube + */ + void computeCone (sm::vec centre, + sm::vec tip, + float ringoffset, + std::array col, + float r = 1.0f, int segments = 12) + { + // Cone is drawn as a base ring around a centre-of-the-base vertex, an + // intermediate ring which is on the base ring, but has different normals, a + // 'ring' around the tip (with suitable normals) and a 'tip' vertex + + sm::vec vbase = centre; + sm::vec vtip = tip; + sm::vec v = vtip - vbase; + v.renormalize(); + + // circle in a plane defined by a point and a normal + sm::vec rand_vec; + rand_vec.randomize(); + sm::vec inplane = rand_vec.cross(v); + inplane.renormalize(); + sm::vec v_x_inplane = v.cross(inplane); + + // Push the central point of the start cap - this is at location vstart + this->vertex_push (vbase, this->vertexPositions); + this->vertex_push (-v, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + // Base ring with normals in direction -v + for (int j = 0; j < segments; j++) { + float t = j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = inplane * std::sin(t) * r + v_x_inplane * std::cos(t) * r; + // Subtract the vector which makes this circle + c = c + (v * ringoffset); + this->vertex_push (vbase+c, this->vertexPositions); + this->vertex_push (-v, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + } + + // Intermediate ring of vertices around/aligned with the base ring with normals in direction c + for (int j = 0; j < segments; j++) { + float t = j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = inplane * std::sin(t) * r + v_x_inplane * std::cos(t) * r; + c = c + (v * ringoffset); + this->vertex_push (vbase+c, this->vertexPositions); + c.renormalize(); + this->vertex_push (c, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + } + + // Intermediate ring of vertices around the tip with normals direction c + for (int j = 0; j < segments; j++) { + float t = j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = inplane * std::sin(t) * r + v_x_inplane * std::cos(t) * r; + c = c + (v * ringoffset); + this->vertex_push (vtip, this->vertexPositions); + c.renormalize(); + this->vertex_push (c, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + } + + // Push tip vertex as the last vertex, normal is in direction v + this->vertex_push (vtip, this->vertexPositions); + this->vertex_push (v, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + // Number of vertices = segments * 3 + 2. + int nverts = segments * 3 + 2; + + // After creating vertices, push all the indices. + GLuint capMiddle = this->idx; + GLuint capStartIdx = this->idx + 1; + GLuint endMiddle = this->idx + static_cast(nverts) - 1u; + GLuint endStartIdx = capStartIdx; + + // Base of the cone + for (int j = 0; j < segments-1; j++) { + this->indices.push_back (capMiddle); + this->indices.push_back (capStartIdx + j); + this->indices.push_back (capStartIdx + 1 + j); + } + // Last tri of base + this->indices.push_back (capMiddle); + this->indices.push_back (capStartIdx + segments - 1); + this->indices.push_back (capStartIdx); + + // Middle sections + for (int lsection = 0; lsection < 2; ++lsection) { + capStartIdx = this->idx + 1 + lsection*segments; + endStartIdx = capStartIdx + segments; + for (int j = 0; j < segments; j++) { + // Triangle 1: + this->indices.push_back (capStartIdx + j); + if (j == (segments-1)) { + this->indices.push_back (capStartIdx); + } else { + this->indices.push_back (capStartIdx + 1 + j); + } + this->indices.push_back (endStartIdx + j); + // Triangle 2: + this->indices.push_back (endStartIdx + j); + if (j == (segments-1)) { + this->indices.push_back (endStartIdx); + } else { + this->indices.push_back (endStartIdx + 1 + j); + } + if (j == (segments-1)) { + this->indices.push_back (capStartIdx); + } else { + this->indices.push_back (capStartIdx + j + 1); + } + } + } + + // tip + for (int j = 0; j < segments-1; j++) { + this->indices.push_back (endMiddle); + this->indices.push_back (endStartIdx + j); + this->indices.push_back (endStartIdx + 1 + j); + } + // Last triangle of tip + this->indices.push_back (endMiddle); + this->indices.push_back (endStartIdx + segments - 1); + this->indices.push_back (endStartIdx); + + // Update idx + this->idx += nverts; + } // end of cone calculation + + //! Compute a line with a single colour + void computeLine (sm::vec start, sm::vec end, + sm::vec _uz, + std::array col, + float w = 0.1f, float thickness = 0.01f, float shorten = 0.0f) + { + this->computeLine (start, end, _uz, col, col, w, thickness, shorten); + } + + /*! + * Create a line from \a start to \a end, with width \a w and a colour which + * transitions from the colour \a colStart to \a colEnd. The thickness of the + * line in the z direction is \a thickness + * + * \param start The start of the tube + * \param end The end of the tube + * \param _uz Dirn of z (up) axis for end face of line. Should be normalized. + * \param colStart The tube staring colour + * \param colEnd The tube's ending colour + * \param w width of line + * \param thickness The thickness/depth of the line in uy direction + * \param shorten An amount by which to shorten the length of the line at each end. + */ + void computeLine (sm::vec start, sm::vec end, + sm::vec _uz, + std::array colStart, std::array colEnd, + float w = 0.1f, float thickness = 0.01f, float shorten = 0.0f) + { + // There are always 8 segments for this line object, 2 at each of 4 corners + const int segments = 8; + + // The vector from start to end defines direction of the tube + sm::vec vstart = start; + sm::vec vend = end; + sm::vec v = vend - vstart; + v.renormalize(); + + // If shorten is not 0, then modify vstart and vend + if (shorten > 0.0f) { + vstart = start + v * shorten; + vend = end - v * shorten; + } + + // vv is normal to v and _uz + sm::vec vv = v.cross(_uz); + vv.renormalize(); + + // Push the central point of the start cap - this is at location vstart + this->vertex_push (vstart, this->vertexPositions); + this->vertex_push (-v, this->vertexNormals); + this->vertex_push (colStart, this->vertexColors); + + // Compute the 'face angles' that will give the correct width and thickness for the line + std::array angles; + float w_ = w * 0.5f; + float d_ = thickness * 0.5f; + float r = std::sqrt (w_ * w_ + d_ * d_); + angles[0] = std::acos (w_ / r); + angles[1] = angles[0]; + angles[2] = sm::mathconst::pi - angles[0]; + angles[3] = angles[2]; + angles[4] = sm::mathconst::pi + angles[0]; + angles[5] = angles[4]; + angles[6] = sm::mathconst::two_pi - angles[0]; + angles[7] = angles[6]; + // The normals for the vertices around the line + std::array, 8> norms = { vv, _uz, _uz, -vv, -vv, -_uz, -_uz, vv }; + + // Start cap vertices (a triangle fan) + for (int j = 0; j < segments; j++) { + sm::vec c = _uz * std::sin(angles[j]) * r + vv * std::cos(angles[j]) * r; + this->vertex_push (vstart+c, this->vertexPositions); + this->vertex_push (-v, this->vertexNormals); + this->vertex_push (colStart, this->vertexColors); + } + + // Intermediate, near start cap. Normals point outwards. Need Additional vertices + for (int j = 0; j < segments; j++) { + sm::vec c = _uz * std::sin(angles[j]) * r + vv * std::cos(angles[j]) * r; + this->vertex_push (vstart+c, this->vertexPositions); + this->vertex_push (norms[j], this->vertexNormals); + this->vertex_push (colStart, this->vertexColors); + } + + // Intermediate, near end cap. Normals point in direction c + for (int j = 0; j < segments; j++) { + sm::vec c = _uz * std::sin(angles[j]) * r + vv * std::cos(angles[j]) * r; + this->vertex_push (vend+c, this->vertexPositions); + this->vertex_push (norms[j], this->vertexNormals); + this->vertex_push (colEnd, this->vertexColors); + } + + // Bottom cap vertices + for (int j = 0; j < segments; j++) { + sm::vec c = _uz * std::sin(angles[j]) * r + vv * std::cos(angles[j]) * r; + this->vertex_push (vend+c, this->vertexPositions); + this->vertex_push (v, this->vertexNormals); + this->vertex_push (colEnd, this->vertexColors); + } + + // Bottom cap. Push centre vertex as the last vertex. + this->vertex_push (vend, this->vertexPositions); + this->vertex_push (v, this->vertexNormals); + this->vertex_push (colEnd, this->vertexColors); + + // Number of vertices = segments * 4 + 2. + int nverts = (segments * 4) + 2; + + // After creating vertices, push all the indices. + GLuint capMiddle = this->idx; + GLuint capStartIdx = this->idx + 1u; + GLuint endMiddle = this->idx + static_cast(nverts) - 1u; + GLuint endStartIdx = capStartIdx + (3u * segments); + + // Start cap indices + for (int j = 0; j < segments-1; j++) { + this->indices.push_back (capMiddle); + this->indices.push_back (capStartIdx + j); + this->indices.push_back (capStartIdx + 1 + j); + } + // Last one + this->indices.push_back (capMiddle); + this->indices.push_back (capStartIdx + segments - 1); + this->indices.push_back (capStartIdx); + + // Middle sections + for (int lsection = 0; lsection < 3; ++lsection) { + capStartIdx = this->idx + 1 + lsection*segments; + endStartIdx = capStartIdx + segments; + for (int j = 0; j < segments; j++) { + this->indices.push_back (capStartIdx + j); + if (j == (segments-1)) { + this->indices.push_back (capStartIdx); + } else { + this->indices.push_back (capStartIdx + 1 + j); + } + this->indices.push_back (endStartIdx + j); + this->indices.push_back (endStartIdx + j); + if (j == (segments-1)) { + this->indices.push_back (endStartIdx); + } else { + this->indices.push_back (endStartIdx + 1 + j); + } + if (j == (segments-1)) { + this->indices.push_back (capStartIdx); + } else { + this->indices.push_back (capStartIdx + j + 1); + } + } + } + + // bottom cap + for (int j = 0; j < segments-1; j++) { + this->indices.push_back (endMiddle); + this->indices.push_back (endStartIdx + j); + this->indices.push_back (endStartIdx + 1 + j); + } + this->indices.push_back (endMiddle); + this->indices.push_back (endStartIdx + segments - 1); + this->indices.push_back (endStartIdx); + + // Update idx + this->idx += nverts; + } // end computeLine + + // Like computeLine, but this line has no thickness. + void computeFlatLine (sm::vec start, sm::vec end, + sm::vec _uz, + std::array col, + float w = 0.1f, float shorten = 0.0f) + { + // The vector from start to end defines direction of the tube + sm::vec vstart = start; + sm::vec vend = end; + sm::vec v = vend - vstart; + v.renormalize(); + + // If shorten is not 0, then modify vstart and vend + if (shorten > 0.0f) { + vstart = start + v * shorten; + vend = end - v * shorten; + } + + // vv is normal to v and _uz + sm::vec vv = v.cross(_uz); + vv.renormalize(); + + // corners of the line, and the start angle is determined from vv and w + sm::vec ww = vv * w * 0.5f; + sm::vec c1 = vstart + ww; + sm::vec c2 = vstart - ww; + sm::vec c3 = vend - ww; + sm::vec c4 = vend + ww; + + this->vertex_push (c1, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + this->vertex_push (c2, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + this->vertex_push (c3, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + this->vertex_push (c4, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + // Number of vertices = segments * 4 + 2. + int nverts = 4; + + // After creating vertices, push all the indices. + this->indices.push_back (this->idx); + this->indices.push_back (this->idx+1); + this->indices.push_back (this->idx+2); + + this->indices.push_back (this->idx); + this->indices.push_back (this->idx+2); + this->indices.push_back (this->idx+3); + + // Update idx + this->idx += nverts; + + } // end computeFlatLine + + // Like computeFlatLine but with option to add rounded start/end caps (I lazily + // draw a whole circle around start/end to achieve this, rather than figuring + // out a semi-circle). + void computeFlatLineRnd (sm::vec start, sm::vec end, + sm::vec _uz, + std::array col, + float w = 0.1f, float shorten = 0.0f, bool startcaps = true, bool endcaps = true) + { + // The vector from start to end defines direction of the tube + sm::vec vstart = start; + sm::vec vend = end; + sm::vec v = vend - vstart; + v.renormalize(); + + // If shorten is not 0, then modify vstart and vend + if (shorten > 0.0f) { + vstart = start + v * shorten; + vend = end - v * shorten; + } + + // vv is normal to v and _uz + sm::vec vv = v.cross(_uz); + vv.renormalize(); + + // corners of the line, and the start angle is determined from vv and w + sm::vec ww = vv * w * 0.5f; + sm::vec c1 = vstart + ww; + sm::vec c2 = vstart - ww; + sm::vec c3 = vend - ww; + sm::vec c4 = vend + ww; + + int segments = 12; + float r = 0.5f * w; + unsigned int startvertices = 0u; + if (startcaps) { + // Push the central point of the start cap - this is at location vstart + this->vertex_push (vstart, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + ++startvertices; + // Start cap vertices (a triangle fan) + for (int j = 0; j < segments; j++) { + float t = j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = { std::sin(t) * r, std::cos(t) * r, 0.0f }; + this->vertex_push (vstart+c, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + ++startvertices; + } + } + + this->vertex_push (c1, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + this->vertex_push (c2, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + this->vertex_push (c3, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + this->vertex_push (c4, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + unsigned int endvertices = 0u; + if (endcaps) { + // Push the central point of the end cap - this is at location vend + this->vertex_push (vend, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + ++endvertices; + // End cap vertices (a triangle fan) + for (int j = 0; j < segments; j++) { + float t = j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c = { std::sin(t) * r, std::cos(t) * r, 0.0f }; + this->vertex_push (vend+c, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + ++endvertices; + } + } + + // After creating vertices, push all the indices. + + if (startcaps) { // prolly startcaps, for flexibility + GLuint topcap = this->idx; + for (int j = 0; j < segments; j++) { + int inc1 = 1+j; + int inc2 = 1+((j+1)%segments); + this->indices.push_back (topcap); + this->indices.push_back (topcap+inc1); + this->indices.push_back (topcap+inc2); + } + this->idx += startvertices; + } + + // The line itself + this->indices.push_back (this->idx); + this->indices.push_back (this->idx+1); + this->indices.push_back (this->idx+2); + this->indices.push_back (this->idx); + this->indices.push_back (this->idx+2); + this->indices.push_back (this->idx+3); + // Update idx + this->idx += 4; + + if (endcaps) { + GLuint botcap = this->idx; + for (int j = 0; j < segments; j++) { + int inc1 = 1+j; + int inc2 = 1+((j+1)%segments); + this->indices.push_back (botcap); + this->indices.push_back (botcap+inc1); + this->indices.push_back (botcap+inc2); + } + this->idx += endvertices; + } + } // end computeFlatLine + + /*! + * Like computeFlatLine, but this line has no thickness and you can provide the + * previous and next data points so that this line, the previous line and the + * next line can line up perfectly without drawing a circular rounded 'end cap'! + * + * This code assumes that the coordinates prev, start, end, next all lie on a 2D + * plane normal to _uz. In fact, the 3D coordinates start, end, prev and next + * will all be projected onto the plane defined by _uz, so that they can be + * reduced to 2D coordinates. This then allows crossing points of lines to be + * computed. + * + * If you want to make a ribbon between points that do *not* lie on a 2D plane, + * you'll need to write another graphics primitive function. + */ + void computeFlatLine (sm::vec start, sm::vec end, + sm::vec prev, sm::vec next, + sm::vec _uz, + std::array col, + float w = 0.1f) + { + // Corner coordinates for this line section + sm::vec c1 = { 0.0f }; + sm::vec c2 = { 0.0f }; + sm::vec c3 = { 0.0f }; + sm::vec c4 = { 0.0f }; + + // Ensure _uz is a unit vector + sm::vec __uz = _uz; + __uz.renormalize(); + + // First find the rotation to make __uz into the actual unit z dirn + sm::quaternion rotn; + sm::vec basis_rotn_axis = __uz.cross (sm::vec<>::uz()); + if (basis_rotn_axis.length() > 0.0f) { + float basis_rotn_angle = __uz.angle (sm::vec<>::uz(), basis_rotn_axis); + rotn.rotate (basis_rotn_axis, basis_rotn_angle); + } // else nothing to do - basis rotn is null + + // Transform so that start is the origin + // sm::vec s_o = { 0.0f }; // by defn + sm::vec e_o = end - start; + sm::vec p_o = prev - start; + sm::vec n_o = next - start; + + // Apply basis rotation just to the end point. e_b: 'end point in rotated basis' + sm::vec e_b = rotn * e_o; + + // Use the vector from start to end as the in-plane x dirn. Do this AFTER + // first coord rotn. In other words: find the rotation about the new unit z + // direction to force the end point to be on the x axis + sm::vec plane_x = e_b; // - s_b but s_b is (0,0,0) by defn + plane_x.renormalize(); + sm::vec plane_y = sm::vec<>::uz().cross (plane_x); + plane_y.renormalize(); + // Find the in-plane coordinates in the rotated plane system + sm::vec e_p = { plane_x.dot (e_b), plane_y.dot (e_b), sm::vec<>::uz().dot (e_b) }; + + // One epsilon is exacting + if (std::abs(e_p[2]) > std::numeric_limits::epsilon()) { + throw std::runtime_error ("uz not orthogonal to the line start -> end?"); + } + + // From e_p and e_b (which should both be in a 2D plane) figure out what + // angle of rotation brings e_b into the x axis + float inplane_rotn_angle = e_b.angle (e_p, sm::vec<>::uz()); + sm::quaternion inplane_rotn (sm::vec<>::uz(), inplane_rotn_angle); + + // Apply the in-plane rotation to the basis rotation + rotn.premultiply (inplane_rotn); + + // Transform points + sm::vec p_p = rotn * p_o; + sm::vec n_p = rotn * n_o; + //vec s_p = rotn * s_o; // not necessary, s_p = (0,0,0) by defn + + // Line crossings time. + sm::vec c1_p = { 0.0f }; // 2D crossing coords that we're going to find + sm::vec c2_p = { 0.0f }; + sm::vec c3_p = e_p.less_one_dim(); + sm::vec c4_p = e_p.less_one_dim(); + + // 3 lines on each side. l_p, l_c (current) and l_n. Each has two ends. l_p_1, l_p_2 etc. + + // 'prev' 'cur' and 'next' vectors + sm::vec p_vec = (/*s_p*/ -p_p).less_one_dim(); + sm::vec c_vec = e_p.less_one_dim(); + sm::vec n_vec = (n_p - e_p).less_one_dim(); + + sm::vec p_ortho = (/*s_p*/ - p_p).cross (sm::vec<>::uz()).less_one_dim(); + p_ortho.renormalize(); + sm::vec c_ortho = (e_p /*- s_p*/).cross (sm::vec<>::uz()).less_one_dim(); + c_ortho.renormalize(); + sm::vec n_ortho = (n_p - e_p).cross (sm::vec<>::uz()).less_one_dim(); + n_ortho.renormalize(); + + const float hw = w / 2.0f; + + sm::vec l_p_1 = p_p.less_one_dim() + (p_ortho * hw) - p_vec; // makes it 3 times as long as the line. + sm::vec l_p_2 = /*s_p.less_one_dim() +*/ (p_ortho * hw) + p_vec; + sm::vec l_c_1 = /*s_p.less_one_dim() +*/ (c_ortho * hw) - c_vec; + sm::vec l_c_2 = e_p.less_one_dim() + (c_ortho * hw) + c_vec; + sm::vec l_n_1 = e_p.less_one_dim() + (n_ortho * hw) - n_vec; + sm::vec l_n_2 = n_p.less_one_dim() + (n_ortho * hw) + n_vec; + + std::bitset<2> isect = sm::geometry::segments_intersect (l_p_1, l_p_2, l_c_1, l_c_2); + if (isect.test(0) == true && isect.test(1) == false) { // test for intersection but not colinear + c1_p = sm::geometry::crossing_point (l_p_1, l_p_2, l_c_1, l_c_2); + } else if (isect.test(0) == true && isect.test(1) == true) { + c1_p = /*s_p.less_one_dim() +*/ (c_ortho * hw); + } else { // no intersection. prev could have been start + c1_p = /*s_p.less_one_dim() +*/ (c_ortho * hw); + } + isect = sm::geometry::segments_intersect (l_c_1, l_c_2, l_n_1, l_n_2); + if (isect.test(0) == true && isect.test(1) == false) { + c4_p = sm::geometry::crossing_point (l_c_1, l_c_2, l_n_1, l_n_2); + } else if (isect.test(0) == true && isect.test(1) == true) { + c4_p = e_p.less_one_dim() + (c_ortho * hw); + } else { // no intersection, prev could have been end + c4_p = e_p.less_one_dim() + (c_ortho * hw); + } + + // o for 'other side'. Could re-use vars in future version. Or just subtract (*_ortho * w) from each. + sm::vec o_l_p_1 = p_p.less_one_dim() - (p_ortho * hw) - p_vec; // makes it 3 times as long as the line. + sm::vec o_l_p_2 = /*s_p.less_one_dim()*/ - (p_ortho * hw) + p_vec; + sm::vec o_l_c_1 = /*s_p.less_one_dim()*/ - (c_ortho * hw) - c_vec; + sm::vec o_l_c_2 = e_p.less_one_dim() - (c_ortho * hw) + c_vec; + sm::vec o_l_n_1 = e_p.less_one_dim() - (n_ortho * hw) - n_vec; + sm::vec o_l_n_2 = n_p.less_one_dim() - (n_ortho * hw) + n_vec; + + isect = sm::geometry::segments_intersect (o_l_p_1, o_l_p_2, o_l_c_1, o_l_c_2); + if (isect.test(0) == true && isect.test(1) == false) { // test for intersection but not colinear + c2_p = sm::geometry::crossing_point (o_l_p_1, o_l_p_2, o_l_c_1, o_l_c_2); + } else if (isect.test(0) == true && isect.test(1) == true) { + c2_p = /*s_p.less_one_dim()*/ - (c_ortho * hw); + } else { // no intersection. prev could have been start + c2_p = /*s_p.less_one_dim()*/ - (c_ortho * hw); + } + + isect = sm::geometry::segments_intersect (o_l_c_1, o_l_c_2, o_l_n_1, o_l_n_2); + if (isect.test(0) == true && isect.test(1) == false) { + c3_p = sm::geometry::crossing_point (o_l_c_1, o_l_c_2, o_l_n_1, o_l_n_2); + } else if (isect.test(0) == true && isect.test(1) == true) { + c3_p = e_p.less_one_dim() - (c_ortho * hw); + } else { // no intersection. next could have been end + c3_p = e_p.less_one_dim() - (c_ortho * hw); + } + + // Transform and rotate back into c1-c4 + sm::quaternion rotn_inv = rotn.invert(); + c1 = rotn_inv * c1_p.plus_one_dim() + start; + c2 = rotn_inv * c2_p.plus_one_dim() + start; + c3 = rotn_inv * c3_p.plus_one_dim() + start; + c4 = rotn_inv * c4_p.plus_one_dim() + start; + + // Now create the vertices from these four corners, c1-c4 + this->vertex_push (c1, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + this->vertex_push (c2, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + this->vertex_push (c3, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + this->vertex_push (c4, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + this->indices.push_back (this->idx); + this->indices.push_back (this->idx+1); + this->indices.push_back (this->idx+2); + + this->indices.push_back (this->idx); + this->indices.push_back (this->idx+2); + this->indices.push_back (this->idx+3); + + // Update idx + this->idx += 4; + } // end computeFlatLine that joins perfectly + + //! Make a joined up line with previous. + void computeFlatLineP (sm::vec start, sm::vec end, + sm::vec prev, + sm::vec _uz, + std::array col, + float w = 0.1f) + { + this->computeFlatLine (start, end, prev, end, _uz, col, w); + } // end computeFlatLine that joins perfectly with prev + + //! Flat line, joining up with next + void computeFlatLineN (sm::vec start, sm::vec end, + sm::vec next, + sm::vec _uz, + std::array col, + float w = 0.1f) + { + this->computeFlatLine (start, end, start, next, _uz, col, w); + } + + // Like computeLine, but this line has no thickness and it's dashed. + // dashlen: the length of dashes + // gap prop: The proportion of dash length used for the gap + void computeFlatDashedLine (sm::vec start, sm::vec end, + sm::vec _uz, + std::array col, + float w = 0.1f, float shorten = 0.0f, + float dashlen = 0.1f, float gapprop = 0.3f) + { + if (dashlen == 0.0f) { return; } + + // The vector from start to end defines direction of the line + sm::vec vstart = start; + sm::vec vend = end; + + sm::vec v = vend - vstart; + float linelen = v.length(); + v.renormalize(); + + // If shorten is not 0, then modify vstart and vend + if (shorten > 0.0f) { + vstart = start + v * shorten; + vend = end - v * shorten; + linelen = v.length() - shorten * 2.0f; + } + + // vv is normal to v and _uz + sm::vec vv = v.cross(_uz); + vv.renormalize(); + + // Loop, creating the dashes + sm::vec dash_s = vstart; + sm::vec dash_e = dash_s + v * dashlen; + sm::vec dashes = dash_e - vstart; + + while (dashes.length() < linelen) { + + // corners of the line, and the start angle is determined from vv and w + sm::vec ww = vv * w * 0.5f; + sm::vec c1 = dash_s + ww; + sm::vec c2 = dash_s - ww; + sm::vec c3 = dash_e - ww; + sm::vec c4 = dash_e + ww; + + this->vertex_push (c1, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + this->vertex_push (c2, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + this->vertex_push (c3, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + this->vertex_push (c4, this->vertexPositions); + this->vertex_push (_uz, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + + // Number of vertices = segments * 4 + 2. + int nverts = 4; + + // After creating vertices, push all the indices. + this->indices.push_back (this->idx); + this->indices.push_back (this->idx+1); + this->indices.push_back (this->idx+2); + + this->indices.push_back (this->idx); + this->indices.push_back (this->idx+2); + this->indices.push_back (this->idx+3); + + // Update idx + this->idx += nverts; + + // Next dash + dash_s = dash_e + v * dashlen * gapprop; + dash_e = dash_s + v * dashlen; + dashes = dash_e - vstart; + } + + } // end computeFlatDashedLine + + // Compute a flat line circle outline + void computeFlatCircleLine (sm::vec centre, sm::vec norm, sm::vec inplane, float radius, + float linewidth, std::array col, int segments = 128) + { + inplane.renormalize(); + sm::vec norm_x_inplane = norm.cross(inplane); + + float half_lw = linewidth / 2.0f; + float r_in = radius - half_lw; + float r_out = radius + half_lw; + // Inner ring at radius radius-linewidth/2 with normals in direction norm; + // Outer ring at radius radius+linewidth/2 with normals also in direction norm + for (int j = 0; j < segments; j++) { + float t = j * sm::mathconst::two_pi / static_cast(segments); + sm::vec c_in = inplane * std::sin(t) * r_in + norm_x_inplane * std::cos(t) * r_in; + this->vertex_push (centre+c_in, this->vertexPositions); + this->vertex_push (norm, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + sm::vec c_out = inplane * std::sin(t) * r_out + norm_x_inplane * std::cos(t) * r_out; + this->vertex_push (centre+c_out, this->vertexPositions); + this->vertex_push (norm, this->vertexNormals); + this->vertex_push (col, this->vertexColors); + } + // Added 2*segments vertices to vertexPositions + + // After creating vertices, push all the indices. + for (int j = 0; j < segments; j++) { + int jn = (segments + ((j+1) % segments)) % segments; + this->indices.push_back (this->idx+(2*j)); + this->indices.push_back (this->idx+(2*jn)); + this->indices.push_back (this->idx+(2*jn+1)); + this->indices.push_back (this->idx+(2*j)); + this->indices.push_back (this->idx+(2*jn+1)); + this->indices.push_back (this->idx+(2*j+1)); + } + this->idx += 2 * segments; // nverts + + } // end computeFlatCircleLine + + // Compute a flat line circle outline + void computeFlatCircleLine (sm::vec centre, sm::vec norm, float radius, + float linewidth, std::array col, int segments = 128) + { + // circle in a plane defined by a point (v0 = vstart or vend) and a normal + // (v) can be found: Choose random vector vr. A vector inplane = vr ^ v. The + // unit in-plane vector is inplane.normalise. Can now use that vector in the + // plan to define a point on the circle. Note that this starting point on + // the circle is at a random position, which means that this version of + // computeFlatCircleLine is useful for tubes that have quite a few segments. + sm::vec rand_vec; + rand_vec.randomize(); + sm::vec inplane = rand_vec.cross(norm); + // Sub call to the method that takes a normal vector AND an inplane vector: + this->computeFlatCircleLine (centre, norm, inplane, radius, linewidth, col, segments); + } + + // Compute triangles to form a true cuboid from 8 corners. + void computeCuboid (const std::array, 8>& v, const std::array& clr) + { + this->computeFlatQuad (v[0], v[1], v[2], v[3], clr); + this->computeFlatQuad (v[0], v[4], v[5], v[1], clr); + this->computeFlatQuad (v[1], v[5], v[6], v[2], clr); + this->computeFlatQuad (v[2], v[6], v[7], v[3], clr); + this->computeFlatQuad (v[3], v[7], v[4], v[0], clr); + this->computeFlatQuad (v[7], v[6], v[5], v[4], clr); + } + + // Compute a rhombus using the four defining coordinates. The coordinates are named as if + // they were the origin, x, y and z of a right-handed 3D coordinate system. These define three edges + void computeRhombus (const sm::vec& o, const sm::vec& x, const sm::vec& y, const sm::vec& z, + const std::array& clr) + { + // Edge vectors + sm::vec edge1 = x - o; + sm::vec edge2 = y - o; + sm::vec edge3 = z - o; + + // Compute the face normals + sm::vec _n1 = edge1.cross (edge2); + _n1.renormalize(); + sm::vec _n2 = edge2.cross (edge3); + _n2.renormalize(); + sm::vec _n3 = edge1.cross (edge3); + _n3.renormalize(); + + // Push positions and normals for 24 vertices to make up the rhombohedron; 4 for each face. + // Front face + this->vertex_push (o, this->vertexPositions); + this->vertex_push (o + edge1, this->vertexPositions); + this->vertex_push (o + edge3, this->vertexPositions); + this->vertex_push (o + edge1 + edge3, this->vertexPositions); + for (unsigned short i = 0U; i < 4U; ++i) { this->vertex_push (_n3, this->vertexNormals); } + // Top face + this->vertex_push (o + edge3, this->vertexPositions); + this->vertex_push (o + edge1 + edge3, this->vertexPositions); + this->vertex_push (o + edge2 + edge3, this->vertexPositions); + this->vertex_push (o + edge2 + edge1 + edge3, this->vertexPositions); + for (unsigned short i = 0U; i < 4U; ++i) { this->vertex_push (_n1, this->vertexNormals); } + // Back face + this->vertex_push (o + edge2 + edge3, this->vertexPositions); + this->vertex_push (o + edge2 + edge1 + edge3, this->vertexPositions); + this->vertex_push (o + edge2, this->vertexPositions); + this->vertex_push (o + edge2 + edge1, this->vertexPositions); + for (unsigned short i = 0U; i < 4U; ++i) { this->vertex_push (-_n3, this->vertexNormals); } + // Bottom face + this->vertex_push (o + edge2, this->vertexPositions); + this->vertex_push (o + edge2 + edge1, this->vertexPositions); + this->vertex_push (o, this->vertexPositions); + this->vertex_push (o + edge1, this->vertexPositions); + for (unsigned short i = 0U; i < 4U; ++i) { this->vertex_push (-_n1, this->vertexNormals); } + // Left face + this->vertex_push (o + edge2, this->vertexPositions); + this->vertex_push (o, this->vertexPositions); + this->vertex_push (o + edge2 + edge3, this->vertexPositions); + this->vertex_push (o + edge3, this->vertexPositions); + for (unsigned short i = 0U; i < 4U; ++i) { this->vertex_push (-_n2, this->vertexNormals); } + // Right face + this->vertex_push (o + edge1, this->vertexPositions); + this->vertex_push (o + edge1 + edge2, this->vertexPositions); + this->vertex_push (o + edge1 + edge3, this->vertexPositions); + this->vertex_push (o + edge1 + edge2 + edge3, this->vertexPositions); + for (unsigned short i = 0U; i < 4U; ++i) { this->vertex_push (_n2, this->vertexNormals); } + + // Vertex colours are all the same + for (unsigned short i = 0U; i < 24U; ++i) { this->vertex_push (clr, this->vertexColors); } + + // Indices for 6 faces + for (unsigned short i = 0U; i < 6U; ++i) { + this->indices.push_back (this->idx++); + this->indices.push_back (this->idx++); + this->indices.push_back (this->idx--); + this->indices.push_back (this->idx++); + this->indices.push_back (this->idx++); + this->indices.push_back (this->idx++); + } + } // computeCuboid + + // Compute a rectangular cuboid of width (in x), height (in y) and depth (in z). + void computeRectCuboid (const sm::vec& o, const float wx, const float hy, const float dz, + const std::array& clr) + { + sm::vec px = o + sm::vec{wx, 0, 0}; + sm::vec py = o + sm::vec{0, hy, 0}; + sm::vec pz = o + sm::vec{0, 0, dz}; + this->computeRhombus (o, px, py, pz, clr); + } + + // Compute the bounding box frame + void computeBoundingBox() + { + // Draw a frame of tubes from bb.min to bb.max + const float& x0 = this->bb.min[0]; + const float& y0 = this->bb.min[1]; + const float& z0 = this->bb.min[2]; + + const float& x1 = this->bb.max[0]; + const float& y1 = this->bb.max[1]; + const float& z1 = this->bb.max[2]; + + const sm::vec& c0 = this->bb.min; + sm::vec c1 = { x1, y0, z0 }; + sm::vec c2 = { x1, y1, z0 }; + sm::vec c3 = { x0, y1, z0 }; + + sm::vec c4 = { x0, y0, z1 }; + sm::vec c5 = { x1, y0, z1 }; + const sm::vec& c6 = this->bb.max; + sm::vec c7 = { x0, y1, z1 }; + + constexpr int segs = 4; + constexpr float zrot = 0.0f; + auto cl = this->colour_bb; + + // Frame tube radius + float r = this->bb.span().length() / 500.0f; + + // Base + this->computeTube (c0, c1, sm::vec::uy(), sm::vec::uz(), cl, cl, r, segs, zrot, true); + this->computeTube (c1, c2, -sm::vec::ux(), sm::vec::uz(), cl, cl, r, segs, zrot, true); + this->computeTube (c2, c3, -sm::vec::uy(), sm::vec::uz(), cl, cl, r, segs, zrot, true); + this->computeTube (c3, c0, sm::vec::ux(), sm::vec::uz(), cl, cl, r, segs, zrot, true); + // Top + this->computeTube (c4, c5, sm::vec::uy(), sm::vec::uz(), cl, cl, r, segs, zrot, true); + this->computeTube (c5, c6, -sm::vec::ux(), sm::vec::uz(), cl, cl, r, segs, zrot, true); + this->computeTube (c6, c7, -sm::vec::uy(), sm::vec::uz(), cl, cl, r, segs, zrot, true); + this->computeTube (c7, c4, sm::vec::ux(), sm::vec::uz(), cl, cl, r, segs, zrot, true); + // Sides + this->computeTube (c0, c4, sm::vec::uy(), -sm::vec::ux(), cl, cl, r, segs, zrot, true); + this->computeTube (c1, c5, sm::vec::uy(), -sm::vec::ux(), cl, cl, r, segs, zrot, true); + this->computeTube (c2, c6, sm::vec::uy(), -sm::vec::ux(), cl, cl, r, segs, zrot, true); + this->computeTube (c3, c7, sm::vec::uy(), -sm::vec::ux(), cl, cl, r, segs, zrot, true); } }; diff --git a/mplot/VisualModelBase.h b/mplot/VisualModelBase.h deleted file mode 100644 index 09907cbd..00000000 --- a/mplot/VisualModelBase.h +++ /dev/null @@ -1,3330 +0,0 @@ -/*! - * \file - * - * Declares a VisualModel base class to hold the vertices that make up some individual model object - * that can be part of an OpenGL scene. - * - * GL function calls are added in VisualModel.h - * - * \author Seb James - * \date March 2025 - */ - -#pragma once - -#if defined __gl3_h_ || defined __gl_h_ -// GL headers have been externally included -#else -// Include GLAD header -# define GLAD_GL_IMPLEMENTATION -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -import sm.geometry_polyhedra; -import sm.quaternion; -import sm.mat; -import sm.vec; -import sm.vvec; -import sm.range; -import sm.algo; -import sm.flags; - -// Need to import common here -import mplot.visualcommon; - -//import mplot.core;// Can I avoid use of this in VisualModelBase? - -#include -#include -#include - -namespace mplot -{ - union float_bytes // for gltf output - { - float f; - uint8_t bytes[sizeof(float)]; - }; - - //! Forward declaration of a Visual class - // Right now, models need to know about VisualBase to: - // get shader progs - // set/get context - // - // Could I have a singleton that can do the work and is a separate class so taht VisualModel no - // longer needs to know about VisualBase? Visual registers its identity and the shader programs - // and the singleton could set context based on an id that the VisualModel contains? - template class VisualBase; - - /*! - * OpenGL model base class - * - * This class is a base 'OpenGL model' class. It has the common code to create the vertices for - * some individual OpengGL model which is to be rendered in a 3-D scene. - * - * This class contains some common 'object primitives' code, such as computeSphere and - * computeCone, which compute the vertices that will make up sphere and cone, respectively. - * - * It contains no GL function calls, these are added in the derived classes VisualModel. - */ - template - struct VisualModelBase - { - VisualModelBase() {} - VisualModelBase (const sm::vec _offset) { this->viewmatrix.translate (_offset); } - - /*! - * Set up the passed-in VisualTextModel with functions that need access to the parent Visual attributes. - */ - template - void bindmodel (std::unique_ptr& model) - { - if (this->parentVis == nullptr) { - throw std::runtime_error ("Can't bind a model, because I am not bound"); - } - model->set_parent (this->parentVis); -#if 0 - model->get_shaderprogs = &mplot::VisualBase::get_shaderprogs; - model->get_gprog = &mplot::VisualBase::get_gprog; - model->get_tprog = &mplot::VisualBase::get_tprog; - model->setContext = &mplot::VisualBase::set_context; - model->releaseContext = &mplot::VisualBase::release_context; -#endif - } - - //! Common code to call after the vertices have been set up. GL has to have been initialised. - virtual void postVertexInit() = 0; - - //! Initialize vertex buffer objects and vertex array object. Empty for 'text only' VisualModels. - virtual void initializeVertices() = 0; - - //! Process vertices and find the bounding box - void update_bb() - { - if (this->flags.test (vm_bools::compute_bb) == false) { return; } - - if (this->vertexPositions.size() % 3 != 0) { - throw std::runtime_error ("VisualModelBase: vertexPositions size is not divisible by 3"); - } - this->bb.search_init(); - for (std::size_t i = 0; i < this->vertexPositions.size(); i += 3) { - this->bb.update (sm::vec{ vertexPositions[i], vertexPositions[i+1], vertexPositions[i+2] }); - } - // After finding the bounding box, make up the vertices to display it: - this->computeBoundingBox(); - } - - /*! - * Re-initialize the buffers. Client code might have appended to - * vertexPositions/Colors/Normals and indices before calling this method. - */ - virtual void reinit_buffers() = 0; - - //! reinit ONLY vertexColors buffer - virtual void reinit_colour_buffer() = 0; - - virtual void clearTexts() = 0; - - //! Clear out the model, *including text models* - void clear() - { - this->vertexPositions.clear(); - this->vertexNormals.clear(); - this->vertexColors.clear(); - this->indices.clear(); - this->clearTexts(); - this->idx = 0u; - // Clear bounding box - this->vpos_bb.clear(); - this->vnorm_bb.clear(); - this->vcol_bb.clear(); - this->indices_bb.clear(); - this->idx_bb = 0u; - - this->reinit_buffers(); - } - - //! Re-create the model - called after updating data - void reinit() - { - if (this->setContext != nullptr) { - this->setContext (this->parentVis); - } - // Fixme: Better not to clear, then repeatedly pushback here: - this->vertexPositions.clear(); - this->vertexNormals.clear(); - this->vertexColors.clear(); - this->indices.clear(); - - // Clear any bounding box too - this->vpos_bb.clear(); - this->vnorm_bb.clear(); - this->vcol_bb.clear(); - this->indices_bb.clear(); - this->idx_bb = 0u; - - // NB: Do NOT call clearTexts() here! We're only updating the model itself. - this->idx = 0u; - this->initializeVertices(); - this->update_bb(); - this->reinit_buffers(); - } - - /*! - * For some models it's important to clear the texts when reinitialising. This is NOT the - * same as VisualModel::clear() followed by initializeVertices(). For the same effect, you - * can call clearTexts() then reinit(). - */ - void reinit_with_clearTexts() - { - if (this->setContext != nullptr) { this->setContext (this->parentVis); } - this->vertexPositions.clear(); - this->vertexNormals.clear(); - this->vertexColors.clear(); - this->indices.clear(); - - this->clearTexts(); - this->idx = 0u; - - // Clear any bounding box too - this->vpos_bb.clear(); - this->vnorm_bb.clear(); - this->vcol_bb.clear(); - this->indices_bb.clear(); - this->idx_bb = 0u; - - this->initializeVertices(); - this->update_bb(); - this->reinit_buffers(); - } - - void reserve_vertices (std::size_t n_vertices) - { - this->vertexPositions.reserve (3u * n_vertices); - this->vertexNormals.reserve (3u * n_vertices); - this->vertexColors.reserve (3u * n_vertices); - this->indices.reserve (6u * n_vertices); - } - - // Make a hash of vertexPositions, etc as an identifier for this model. The hash identifies - // the model's mesh geometry for NavMesh and so the vertexColors are not important. - std::size_t hash() const - { - std::size_t h = 17; - for (std::size_t i = 0u; i < this->vertexPositions.size(); ++i) { - h = (h << 5) - 1 + std::hash{}(this->vertexPositions[i]); - } - for (std::size_t i = 0u; i < this->vertexNormals.size(); ++i) { - h = (h << 5) - 1 + std::hash{}(this->vertexNormals[i]); - } - for (std::size_t i = 0u; i < this->indices.size(); ++i) { - h = (h << 5) - 1 + std::hash{}(this->indices[i]); - } - return h; - } - - // Get a single position from vertexPositions, using the index into the vector - // interpretation of vertexPositions - sm::vec get_position (const uint32_t vec_idx) const - { - auto vp = reinterpret_cast>*>(&this->vertexPositions); - return (*vp)[vec_idx]; - } - - // Get a single normal from vertexNormals, using the index into the vector - // interpretation of vertexNormals - sm::vec get_normal (const uint32_t vec_idx) const - { - auto vn = reinterpret_cast>*>(&this->vertexNormals); - return (*vn)[vec_idx]; - } - - // Get the area of the triangle whose start index is vec_idx - float get_area (const uint32_t vec_idx0, const uint32_t vec_idx1, const uint32_t vec_idx2) const - { - auto vp = reinterpret_cast>*>(&this->vertexPositions); - auto t0 = (*vp)[vec_idx0]; - auto t1 = (*vp)[vec_idx1]; - auto t2 = (*vp)[vec_idx2]; - return sm::geometry::tri_area (t0, t1, t2); - } - - /** - * Neighbour vertex mesh code. - */ - - // Our navigation mesh data struct - std::unique_ptr navmesh; - - void build_navmesh() - { - constexpr bool debug_mn = false; - if constexpr (debug_mn) { std::cout << __func__ << " called" << std::endl; } - - if (!this->navmesh) { return; } - - // Copy the bounding box - navmesh->bb = this->bb; - - // Treat vertexPositions as a vector of vec: - auto vp = reinterpret_cast>*>(&this->vertexPositions); - - uint32_t vps = vp->size(); - std::unordered_map, std::set, sm::vec::hash> equiv_v; - uint32_t i = 0; - for (auto p : *vp) { equiv_v[p].insert (i++); } - std::map> equiv; - for (auto e : equiv_v) { equiv[*e.second.begin()] = e.second; } - if constexpr (debug_mn) { - for (auto e : equiv) { - std::cout << "build_navmesh: equiv[" << e.first << "] = "; - for (auto idx : e.second) { std::cout << idx << ","; } - std::cout << std::endl; - } - std::cout << "build_navmesh: Populated equiv which has " << equiv.size() << " vvecs" << std::endl; - } - - // Make inverse of equiv to translate from original (indices, vertexPositions) index to - // new topographic mesh index - sm::vvec navmesh_idx (vps, 0); - uint32_t vcount = 0; - i = 0; - for (auto eqs : equiv) { - vcount += eqs.second.size(); - for (auto ev : eqs.second) { - if constexpr (debug_mn) { - std::cout << "build_navmesh: set navmesh_idx[" << ev << "] = " << i << std::endl; - } - navmesh_idx[ev] = i; - } - ++i; - } - if constexpr (debug_mn) { std::cout << "build_navmesh: Created equiv inverse" << std::endl; } - - if (vcount != vps) { - std::cout << "build_navmesh: WARNING: Vertex count from equiv is " << vcount - << " which should (but does not) equal " << vps << std::endl; - } - - // Can now populate vertex, a vector of coordinates, if required, or simply access (*vp) - // as needed using equiv.first - navmesh->vertex.resize (equiv.size(), mesh::vertex{}); - i = 0; - for (auto eq : equiv) { - navmesh->vertex[i++] = { (*vp)[eq.first], std::numeric_limits::max() }; - } - - // We're turing a triangle mesh into a navmesh. Don't know what to do if there are stray vertices. - if (this->indices.size() % 3u != 0u) { - throw std::runtime_error ("Uh oh, indices size not divisible by 3!!!! Call the cops!"); - } - - // Lastly, generate edges. For which we require use of indices, which is expressed in - // terms of the old indices. That lookup is navmesh_idx. - for (uint32_t i = 0; i < this->indices.size(); i += 3) { - - // Add three halfedges for the triangle - const uint32_t hesz = navmesh->halfedge.size(); - const uint32_t he0 = hesz; - const uint32_t he1 = hesz + 1; - const uint32_t he2 = hesz + 2; - - if constexpr (debug_mn) { - std::cout << "setting halfedge["<< he0 << "] to { {" - << navmesh_idx[indices[i]] << ", " << navmesh_idx[indices[i + 1]] - << "}, nullptr, " << he1 << ", " << he2 << " }" << std::endl; - - std::cout << "setting halfedge[" << he1 << "] to { {" - << navmesh_idx[indices[i + 1]] << ", " << navmesh_idx[indices[i + 2]] - << "}, nullptr, " << he2 << ", " << he0 << " }" << std::endl; - - std::cout << "setting halfedge[" << he2 << "] to { {" - << navmesh_idx[indices[i + 2]] << ", " << navmesh_idx[indices[i]] - << "}, nullptr, " << he0 << ", " << he1 << " }" << std::endl; - } - - navmesh->halfedge.resize (hesz + 3, {}); - - // Now, could also try to identify LINES - navmesh->halfedge[he0] = { {navmesh_idx[indices[i ]], navmesh_idx[indices[i + 1]]}, std::numeric_limits::max(), he1, he2, 0u }; - navmesh->halfedge[he1] = { {navmesh_idx[indices[i + 1]], navmesh_idx[indices[i + 2]]}, std::numeric_limits::max(), he2, he0, 0u }; - navmesh->halfedge[he2] = { {navmesh_idx[indices[i + 2]], navmesh_idx[indices[i ]]}, std::numeric_limits::max(), he0, he1, 0u }; - - if constexpr (debug_mn) { - std::cout << "halfedge["<< hesz << "] contains: vi:" - << navmesh->halfedge[hesz].vi - << ", twin:" << navmesh->halfedge[hesz].twin - << ", next:" << navmesh->halfedge[hesz].next - << ", prev:" << navmesh->halfedge[hesz].prev << std::endl; - } - // A face contains just the first half edge index - mesh::face<> t = { he0 }; - - // The normal vector for this triangle could be obtained from the mesh normals, but - // we can't trust them (though they're easy to get, as we're dealing with indices - // already). However, use this to ensure that our triangle indices order is in - // agreement with mesh normal as far as direction goes. - sm::vec tn = this->get_normal (indices[i]) + this->get_normal (indices[i + 1]) + this->get_normal (indices[i + 2]) ; - tn.renormalize(); - - // Compute trinorm as well and compare with the one from the mesh - perhaps it's - // different? We really want the right normal. - const sm::vec& tv0 = navmesh->vertex[navmesh_idx[indices[i]]].p; - const sm::vec& tv1 = navmesh->vertex[navmesh_idx[indices[i + 1]]].p; - const sm::vec& tv2 = navmesh->vertex[navmesh_idx[indices[i + 2]]].p; - sm::vec nx = (tv1 - tv0); - sm::vec ny = (tv2 - tv0); - sm::vec n = nx.cross (ny); - n.renormalize(); - - // Check rotational sense of triangles - if (n.dot (tn) < 0.0f) { - std::cout << "Swap order of triangle with he " << he0 << std::endl; - // Swap first and last half edge - navmesh->halfedge[he0].vi.rotate(); - navmesh->halfedge[he1].vi.rotate(); - navmesh->halfedge[he2].vi.rotate(); - } - navmesh->triangles.push_back (t); - } - if constexpr (debug_mn) { - std::cout << "build_navmesh: Created triangles (" << navmesh->halfedge.size() << " halfedges)" << std::endl; - } - - navmesh->compute_neighbour_relations(); // finds the halfedge twins - } - - /*! - * Post-process vertices to generate a neighbour relationship mesh suitable for navigation. - * - * \param navmesh_dir The directory into which to store/read the navmesh data file. - */ - void make_navmesh (std::string navmesh_dir = "") - { - if (this->navmesh) { return; } // already made it - - if (this->flags.test (vm_bools::compute_bb) == false) { - throw std::runtime_error ("make_navmesh requires compute_bb flag to be true"); - } - this->update_bb(); - - // Create a new navmesh - this->navmesh = std::make_unique(); - - // Have we got a pre-computed navmesh file for the halfedge twin relationships? - uint64_t h = this->hash(); - if (navmesh_dir.empty()) { - navmesh_dir = mplot::tools::getTmpPath(); - } else { - if (navmesh_dir.back() != '/') { navmesh_dir += "/"; } - } - std::string filename = navmesh_dir + std::string("navmesh_") + std::to_string (h); - std::string filename_pre_boundary = filename + ".pre"; - - constexpr bool just_mark = true; - if (mplot::tools::fileExists (filename)) { - this->navmesh->load (filename); - std::cout << "Full test...\n"; - this->navmesh->test(); - - } else if (mplot::tools::fileExists (filename_pre_boundary)) { - std::cout << "Pre-boundary navmesh\n"; - this->navmesh->load (filename_pre_boundary); - this->navmesh->add_boundary_halfedges(); - this->navmesh->test (just_mark); - this->navmesh->save (filename); - } else { - std::cout << "Building NavMesh to save into file " << filename << std::endl; - this->build_navmesh(); - this->navmesh->save (filename_pre_boundary); - this->navmesh->add_boundary_halfedges(); - this->navmesh->test (just_mark); - this->navmesh->save (filename); - } - } - - /** - * End neighbour vertex mesh code - */ - - /*! - * A function to call initialiseVertices and postVertexInit after any necessary attributes - * have been set (see, for example, setting the colour maps up in VisualDataModel). - */ - void finalize() - { - if (this->setContext != nullptr) { this->setContext (this->parentVis); } - this->initializeVertices(); - this->update_bb(); - this->flags.set (vm_bools::postVertexInitRequired, true); - // Release context after creating and finalizing this VisualModel. On Visual::render(), - // context will be re-acquired. - if (this->releaseContext != nullptr) { this->releaseContext (this->parentVis); } - } - - //! Render the VisualModel. Note that it is assumed that the OpenGL context has been - //! obtained by the parent Visual::render call. - virtual void render() = 0; - - //! Setter for the viewmatrix - void setViewMatrix (const sm::mat& mv) { this->viewmatrix = mv; } - //! And a getter - sm::mat getViewMatrix() const { return this->viewmatrix; } - //! Pre or post-multiply - void postmultViewMatrix (const sm::mat& m) { this->viewmatrix = this->viewmatrix * m; } - void premultViewMatrix (const sm::mat& m) { this->viewmatrix = m * this->viewmatrix; } - - void scaleViewMatrix (const float by) { this->viewmatrix.scale (by); } - - virtual void setSceneMatrixTexts (const sm::mat& sv) = 0; - - //! When setting the scene matrix, also have to set the text's scene matrices. - void setSceneMatrix (const sm::mat& sv) - { - this->scenematrix = sv; - this->setSceneMatrixTexts (sv); - } - - virtual void setSceneTranslationTexts (const sm::vec& v0) = 0; - - //! Set a translation into the scene and into any child texts - template requires (N == 3) || (N == 4) - void setSceneTranslation (const sm::vec& v0) - { - this->scenematrix.set_identity(); - this->scenematrix.translate (v0); - if constexpr (N == 4) { - this->setSceneTranslationTexts (v0.less_one_dim()); - } else { - this->setSceneTranslationTexts (v0); - } - } - - //! Set a translation (only) into the scene view matrix - template requires (N == 3) || (N == 4) - void addSceneTranslation (const sm::vec& v0) { this->scenematrix.pretranslate (v0); } - - //! Set a rotation (only) into the scene view matrix - void setSceneRotation (const sm::quaternion& r) - { - this->scenematrix.set_identity(); - this->scenematrix.rotate (r); - } - - //! Add a rotation to the scene view matrix - void addSceneRotation (const sm::quaternion& r) { this->scenematrix.rotate (r); } - - //! Set a translation to the model view matrix - template requires (N == 3) || (N == 4) - void setViewTranslation (const sm::vec& v0) - { - this->viewmatrix.set_identity(); - this->viewmatrix.translate (v0); - } - - //! Add a translation to the model view matrix - template requires (N == 3) || (N == 4) - void addViewTranslation (const sm::vec& v0) { this->viewmatrix.pretranslate (v0); } - - //! Set a rotation (only) into the view, but keep texts fixed - void setViewRotationFixTexts (const sm::quaternion& r) - { - sm::vec<> os = this->viewmatrix.translation(); - this->viewmatrix.set_identity(); - this->viewmatrix.translate (os); - this->viewmatrix.rotate (r); - } - - virtual void setViewRotationTexts (const sm::quaternion& r) = 0; - - //! Set a rotation (only) into the view - void setViewRotation (const sm::quaternion& r) - { - sm::vec<> os = this->viewmatrix.translation(); - this->viewmatrix.set_identity(); - this->viewmatrix.translate (os); - this->viewmatrix.rotate (r); - this->setViewRotationTexts (r); - } - - virtual void addViewRotationTexts (const sm::quaternion& r) = 0; - - //! Apply a further rotation to the model view matrix - void addViewRotation (const sm::quaternion& r) - { - this->viewmatrix.rotate (r); - this->addViewRotationTexts (r); - } - - //! Apply a further rotation to the model view matrix, but keep texts fixed - void addViewRotationFixTexts (const sm::quaternion& r) - { - this->viewmatrix.rotate (r); - } - - // The alpha attribute accessors - void setAlpha (const float _a) { this->alpha = _a; } - float getAlpha() const { return this->alpha; } - void incAlpha() - { - this->alpha += 0.1f; - this->alpha = this->alpha > 1.0f ? 1.0f : this->alpha; - } - void decAlpha() - { - this->alpha -= 0.1f; - this->alpha = this->alpha < 0.0f ? 0.0f : this->alpha; - } - - // The hide attribute accessors - void setHide (const bool _h = true) { this->flags.set (vm_bools::hide, _h); } - void toggleHide() { this->flags.flip (vm_bools::hide); } - float hidden() const { return this->flags.test (vm_bools::hide); } - - /* - * Methods used by Visual::savegltf() - */ - - //! Get model translation in a json-friendly string - std::string translation_str() { return this->viewmatrix.translation().str_mat(); } - //! A getter for the viewmatrix translation of the origin (would be same as viewmatrix.translation) - sm::vec get_viewmatrix_origin() const - { - return (this->viewmatrix * sm::vec{0,0,0}).less_one_dim(); - } - //! The centre of mass of the bounding box may not be the VisualModel's origin - sm::vec get_viewmatrix_bb_centre() const - { - return (this->viewmatrix * this->bb.mid()).less_one_dim(); - } - - //! Apply the viewmatrix to the model's bounding box and return it - sm::range> get_viewmatrix_modelbb() const - { - sm::range> vmbb; - vmbb.min = (this->viewmatrix * this->bb.min).less_one_dim(); - vmbb.max = (this->viewmatrix * this->bb.max).less_one_dim(); - return vmbb; - } - - //! Return the number of elements in this->indices - std::size_t indices_size() { return this->indices.size(); } - float indices_max() { return this->idx_max; } - float indices_min() { return this->idx_min; } - std::size_t indices_bytes() { return this->indices.size() * sizeof (GLuint); } - //! Return base64 encoded version of indices - std::string indices_base64() - { - std::vector idx_bytes (this->indices.size() << 2, 0); - std::size_t b = 0u; - for (auto i : this->indices) { - idx_bytes[b++] = i & 0xff; - idx_bytes[b++] = i >> 8 & 0xff; - idx_bytes[b++] = i >> 16 & 0xff; - idx_bytes[b++] = i >> 24 & 0xff; - } - return base64::encode (idx_bytes); - } - - /*! - * Find the extents of this VisualModel, returning it as the x range, the y range and the z range. - */ - sm::vec, 3> extents() - { - sm::vec, 3> axis_extents; - for (unsigned int i = 0; i < 3; ++i) { axis_extents[i].search_init(); } - for (unsigned int j = 0; j < static_cast(this->vertexPositions.size() - 2); j += 3) { - for (unsigned int i = 0; i < 3; ++i) { axis_extents[i].update (this->vertexPositions[j+i]); } - } - return axis_extents; - } - - /*! - * Compute the max and min values of indices and vertexPositions/Colors/Normals for use - * when saving gltf files - */ - void computeVertexMaxMins() - { - // Compute index maxmins - for (std::size_t i = 0u; i < this->indices.size(); ++i) { - idx_max = this->indices[i] > idx_max ? this->indices[i] : idx_max; - idx_min = this->indices[i] < idx_min ? this->indices[i] : idx_min; - } - // Check every 0th entry in vertex Positions, every 1st, etc for max in the - - if (this->vertexPositions.size() != this->vertexColors.size() - ||this->vertexPositions.size() != this->vertexNormals.size()) { - throw std::runtime_error ("Expect vertexPositions, Colors and Normals vectors all to have same size"); - } - - for (std::size_t i = 0u; i < this->vertexPositions.size(); i+=3u) { - vpos_maxes[0] = (vertexPositions[i] > vpos_maxes[0]) ? vertexPositions[i] : vpos_maxes[0]; - vpos_maxes[1] = (vertexPositions[i+1] > vpos_maxes[1]) ? vertexPositions[i+1] : vpos_maxes[1]; - vpos_maxes[2] = (vertexPositions[i+2] > vpos_maxes[2]) ? vertexPositions[i+2] : vpos_maxes[2]; - vcol_maxes[0] = (vertexColors[i] > vcol_maxes[0]) ? vertexColors[i] : vcol_maxes[0]; - vcol_maxes[1] = (vertexColors[i+1] > vcol_maxes[1]) ? vertexColors[i+1] : vcol_maxes[1]; - vcol_maxes[2] = (vertexColors[i+2] > vcol_maxes[2]) ? vertexColors[i+2] : vcol_maxes[2]; - vnorm_maxes[0] = (vertexNormals[i] > vnorm_maxes[0]) ? vertexNormals[i] : vnorm_maxes[0]; - vnorm_maxes[1] = (vertexNormals[i+1] > vnorm_maxes[1]) ? vertexNormals[i+1] : vnorm_maxes[1]; - vnorm_maxes[2] = (vertexNormals[i+2] > vnorm_maxes[2]) ? vertexNormals[i+2] : vnorm_maxes[2]; - - vpos_mins[0] = (vertexPositions[i] < vpos_mins[0]) ? vertexPositions[i] : vpos_mins[0]; - vpos_mins[1] = (vertexPositions[i+1] < vpos_mins[1]) ? vertexPositions[i+1] : vpos_mins[1]; - vpos_mins[2] = (vertexPositions[i+2] < vpos_mins[2]) ? vertexPositions[i+2] : vpos_mins[2]; - vcol_mins[0] = (vertexColors[i] < vcol_mins[0]) ? vertexColors[i] : vcol_mins[0]; - vcol_mins[1] = (vertexColors[i+1] < vcol_mins[1]) ? vertexColors[i+1] : vcol_mins[1]; - vcol_mins[2] = (vertexColors[i+2] < vcol_mins[2]) ? vertexColors[i+2] : vcol_mins[2]; - vnorm_mins[0] = (vertexNormals[i] < vnorm_mins[0]) ? vertexNormals[i] : vnorm_mins[0]; - vnorm_mins[1] = (vertexNormals[i+1] < vnorm_mins[1]) ? vertexNormals[i+1] : vnorm_mins[1]; - vnorm_mins[2] = (vertexNormals[i+2] < vnorm_mins[2]) ? vertexNormals[i+2] : vnorm_mins[2]; - } - } - - std::size_t vpos_size() { return this->vertexPositions.size(); } - std::string vpos_max() { return this->vpos_maxes.str_mat(); } - std::string vpos_min() { return this->vpos_mins.str_mat(); } - std::size_t vpos_bytes() { return this->vertexPositions.size() * sizeof (float); } - std::string vpos_base64() - { - std::vector _bytes (this->vertexPositions.size() << 2, 0); - std::size_t b = 0u; - float_bytes fb; - for (auto i : this->vertexPositions) { - fb.f = i; - _bytes[b++] = fb.bytes[0]; - _bytes[b++] = fb.bytes[1]; - _bytes[b++] = fb.bytes[2]; - _bytes[b++] = fb.bytes[3]; - } - return base64::encode (_bytes); - } - std::size_t next_vpos_idx = 0; - void init_vpos_accessor() { this->next_vpos_idx = 0; } - sm::vec get_next_vpos() - { - sm::vec pos; - pos.set_from (std::numeric_limits::max()); - if (this->next_vpos_idx < this->vertexPositions.size()) { - sm::vec tmp = { - this->vertexPositions[this->next_vpos_idx], - this->vertexPositions[this->next_vpos_idx + 1], - this->vertexPositions[this->next_vpos_idx + 2] - }; - - pos = (this->viewmatrix * tmp).less_one_dim(); - this->next_vpos_idx += 3; - } - return pos; - } - - std::size_t vcol_size() { return this->vertexColors.size(); } - std::string vcol_max() { return this->vcol_maxes.str_mat(); } - std::string vcol_min() { return this->vcol_mins.str_mat(); } - std::size_t vcol_bytes() { return this->vertexColors.size() * sizeof (float); } - std::string vcol_base64() - { - std::vector _bytes (this->vertexColors.size() << 2, 0); - std::size_t b = 0u; - float_bytes fb; - for (auto i : this->vertexColors) { - fb.f = i; - _bytes[b++] = fb.bytes[0]; - _bytes[b++] = fb.bytes[1]; - _bytes[b++] = fb.bytes[2]; - _bytes[b++] = fb.bytes[3]; - } - return base64::encode (_bytes); - } - std::size_t vnorm_size() { return this->vertexNormals.size(); } - std::string vnorm_max() { return this->vnorm_maxes.str_mat(); } - std::string vnorm_min() { return this->vnorm_mins.str_mat(); } - std::size_t vnorm_bytes() { return this->vertexNormals.size() * sizeof (float); } - std::string vnorm_base64() - { - std::vector _bytes (this->vertexNormals.size()<<2, 0); - std::size_t b = 0u; - float_bytes fb; - for (auto i : this->vertexNormals) { - fb.f = i; - _bytes[b++] = fb.bytes[0]; - _bytes[b++] = fb.bytes[1]; - _bytes[b++] = fb.bytes[2]; - _bytes[b++] = fb.bytes[3]; - } - return base64::encode (_bytes); - } - std::size_t next_vnorm_idx = 0; - void init_vnorm_accessor() { this->next_vnorm_idx = 0; } - sm::vec get_next_vnorm() - { - sm::vec pos; - pos.set_from (std::numeric_limits::max()); - if (this->next_vnorm_idx < this->vertexPositions.size()) { - pos = { this->vertexPositions[this->next_vnorm_idx], - this->vertexPositions[this->next_vnorm_idx + 1], - this->vertexPositions[this->next_vnorm_idx + 2] }; - this->next_vnorm_idx += 3; - } - return pos; - } - // end Visual::savegltf() methods - - // A VisualModel may be given a name - std::string name = {}; - - // The mplot::Visual ID to which I belong. max means unset. - uint32_t visual_id = std::numeric_limits::max(); - - //! The current indices index - GLuint idx = 0u; - GLuint idx_bb = 0u; - - /*! - * This is the upper limit for instance_count. We reserve max_isntances of space in the SSBO. - * - * Max number of instances in a model. Each *model* has to reserve space in the SSBOs which - * are managed by VisualResources. VisualResources::max_instances must be larger than this. - */ - unsigned int max_instances = 16 * 1024; - //! The offset into the SSBOs for the instance data for this VisualModel - unsigned int instance_start = 0; - //! If drawing with instancing, how many instances? <= this->max_instances - unsigned int instance_count = 0; - //! If drawing with instancing, how many params will be used (these will be cycled through - //! per-instance and there may be fewer than instance_count parameters) - unsigned int instparam_count = 0; -#if 0 - /*! - * A function that will be runtime defined to get_shaderprogs from a pointer to - * Visual (saving a boilerplate argument and avoiding that killer circular - * dependency at the cost of one line of boilerplate in client programs) - */ - std::function*)> get_shaderprogs; - //! Get the graphics shader prog id - std::function*)> get_gprog; - //! Get the text shader prog id - std::function*)> get_tprog; - - //! Set OpenGL context. Should call parentVis->setContext(). - std::function*)> setContext; - //! Release OpenGL context. Should call parentVis->releaseContext(). - std::function*)> releaseContext; - - //! Init the SSBOs for instanced rendering - std::function*, const unsigned int)> init_instance_data; - std::function&)> insert_instance_data; - std::function&, const float, const float)> insert_instparam_data; - std::function*)> instanced_needs_update; -#endif - //! Set the scaling matrix for all instances - virtual void set_instance_scale (const float scl) = 0; - - //! Set up the instance positions (with default params for colour, rotn, scale) - virtual void set_instance_data (const sm::vvec>& position) = 0; - - //! Set instance positions, with a single colour, alpha and scale to apply to all points - virtual void set_instance_data (const sm::vvec>& position, - const std::array& colour, - const float alpha, - const float scale) = 0; - - //! Set instance positions, with an array containing colour, alpha and scale values to apply - //! to the instances. The size of colour, alpha and scale must match, but it may be of a - //! different size to position. - virtual void set_instance_data (const sm::vvec>& position, - const sm::vvec>& colour, - const sm::vvec& alpha, - const sm::vvec& scale) = 0; - -#if 0 - //! Update the instance positions and params (colour, rotn, scale) in a range - virtual void update_instance_data (const sm::vvec>& points, const sm::vvec& data, - std::size_t i_s, std::size_t i_e) = 0; -#endif - //! Setter for the parent pointer, parentVis - void set_parent (mplot::VisualBase* _vis) - { - if (this->parentVis != nullptr) { throw std::runtime_error ("VisualModel: Set the parent pointer once only!"); } - this->parentVis = _vis; - } - - // Flags defaults. - constexpr sm::flags flags_defaults() - { - sm::flags _flags; - _flags.set (vm_bools::postVertexInitRequired, false); - _flags.set (vm_bools::twodimensional, false); - _flags.set (vm_bools::hide, false); - _flags.set (vm_bools::wireframe, false); - _flags.set (vm_bools::show_bb, false); - _flags.set (vm_bools::compute_bb, true); - return _flags; - } - - // State/options flags - sm::flags flags = flags_defaults(); - - // Setters for flags - void show_bb (const bool val) { this->flags.set (vm_bools::show_bb, val); } - void compute_bb (const bool val) { this->flags.set (vm_bools::compute_bb, val); } - - //! A range can be used for a bounding box for this VisualModel - sm::range> bb; - std::array colour_bb = mplot::colour::grey90; - - void twodimensional (const bool val) { this->flags.set (vm_bools::twodimensional, val); } - bool twodimensional() const { return this->flags.test (vm_bools::twodimensional); } - - void wireframe (const bool val) { this->flags.set (vm_bools::wireframe, val); } - bool wireframe() const { return this->flags.test (vm_bools::wireframe); } - - void instanced (const bool val) { this->flags.set (vm_bools::instanced, val); } - bool instanced() const { return this->flags.test (vm_bools::instanced); } - - //! Getter for vertex positions (for mplot::NormalsVisual) - std::vector getVertexPositions() { return this->vertexPositions; } - //! Getter for vertex normals (for mplot::NormalsVisual) - std::vector getVertexNormals() { return this->vertexNormals; } - std::vector getVertexColors() { return this->vertexColors; } - - protected: - - //! The model-specific view matrix. Used to transform the pose of the model in the scene. - sm::mat viewmatrix = {}; - /*! - * The scene view matrix. Each VisualModel has a copy of the scenematrix. It's set in - * Visual::render. Different VisualModels may have different scenematrices (for example, the - * CoordArrows has a different scenematrix from other VisualModels, and models marked - * 'twodimensional' also have a different scenematrix). - */ - sm::mat scenematrix = {}; - - /*! - * Instance scaling. This matrix can be used to control the scale of all instances of an - * instanced VisualModel - */ - sm::mat instscale = {}; - - /*! - * The colour for all instances. This is used if you don't set colour in your instance params. - */ - std::array instcolour = mplot::colour::yellow; - - //! Contains the positions within the vbo array of the different vertex buffer objects - enum VBOPos { posnVBO, normVBO, colVBO, idxVBO, numVBO }; - - /* - * Compute positions and colours of vertices for the hexes and store in these: - */ - - //! The OpenGL Vertex Array Object - GLuint vao = 0; - - //! Vertex Buffer Objects stored in an array - std::unique_ptr vbos; - - //! CPU-side data for indices - std::vector indices = {}; - //! CPU-side data for vertex positions - std::vector vertexPositions = {}; - //! CPU-side data for vertex normals - std::vector vertexNormals = {}; - //! CPU-side data for vertex colours - std::vector vertexColors = {}; - - // OpenGL arrays for the bounding box, if needed - GLuint vao_bb = 0; - std::unique_ptr vbos_bb; - std::vector indices_bb = {}; - std::vector vpos_bb = {}; - std::vector vnorm_bb = {}; - std::vector vcol_bb = {}; - - static constexpr float _max = std::numeric_limits::max(); - static constexpr float _low = std::numeric_limits::lowest(); - - // The max and min values in the next 8 attributes are only computed if gltf files are going - // to be output by Visual::savegltf() - - //! Max values of 0th, 1st and 2nd coordinates in vertexPositions - sm::vec vpos_maxes = { _low, _low, _low }; // fixme: same as bounding box! - //! Min values in vertexPositions - sm::vec vpos_mins = { _max, _max, _max }; - sm::vec vcol_maxes = { _low, _low, _low }; - sm::vec vcol_mins = { _max, _max, _max }; - sm::vec vnorm_maxes = { _low, _low, _low }; - sm::vec vnorm_mins = { _max, _max, _max }; - //! Max value in indices - GLuint idx_max = 0u; - //! Min value in indices. - GLuint idx_min = std::numeric_limits::max(); - - //! A model-wide alpha value for the shader - float alpha = 1.0f; - - // The mplot::VisualBase in which this model exists. - mplot::VisualBase* parentVis = nullptr; - - //! Push three floats onto the vector of floats \a vp - void vertex_push (const float& x, const float& y, const float& z, std::vector& vp) - { - vp.emplace_back (x); - vp.emplace_back (y); - vp.emplace_back (z); - } - //! Push array of 3 floats onto the vector of floats \a vp - template requires (N == 3 || N == 4) - void vertex_push (const std::array& arr, std::vector& vp) - { - vp.emplace_back (arr[0]); - vp.emplace_back (arr[1]); - vp.emplace_back (arr[2]); - } - //! Push sm::vec of 3 floats onto the vector of floats \a vp - template requires (N == 3 || N == 4) - void vertex_push (const sm::vec& vec, std::vector& vp) - { - vp.emplace_back (vec[0]); - vp.emplace_back (vec[1]); - vp.emplace_back (vec[2]); - } - - //! Set up a vertex buffer object - bind, buffer and set vertex array object attribute - virtual void setupVBO (GLuint& buf, std::vector& dat, unsigned int bufferAttribPosition) = 0; - - protected: - /*! - * Add the given meshgroup to this VisualModel - */ - void computeMeshgroup (const mplot::meshgroup& mg) - { - mg.validate(); - - bool single_colr = mg.colours.empty(); - for (uint32_t i = 0; i < mg.positions.size(); ++i) { - // We apply mg.transform *here*, rather than writing it into the viewmatrix. This is - // because other elements of this visual model may be added with the assumption of an - // identity viewmatrix. - this->vertex_push (mg.transform * mg.positions[i], this->vertexPositions); - this->vertex_push (mg.transform * mg.normals[i], this->vertexNormals); - if (single_colr) { - this->vertex_push (mg.single_colour, this->vertexColors); - } else { - this->vertex_push (mg.colours[i], this->vertexColors); - } - } - for (uint32_t i = 0; i < mg.indices.size(); ++i) { - this->indices.push_back (mg.indices[i] + this->idx); - } - this->idx += mg.positions.size(); - } - - /** - * START vertex/index computation code - * - * ALL methods below this point are for computing vertices. - * - * The metheds compute vertexPositions/Normals/Colors along with indices in a form suitable - * for use with GL's DrawElements (or DrawElementsInstanced) drawing call. - */ - - /*! - * Create a tube from \a start to \a end, with radius \a r and a colour which - * transitions from the colour \a colStart to \a colEnd. - * - * This version simply sub-calls into computeFlaredTube which will randomly choose the angle - * of the vertices around the centre of each end cap. - * - * \param idx The index into the 'vertex array' - * \param start The start of the tube - * \param end The end of the tube - * \param colStart The tube starting colour - * \param colEnd The tube's ending colour - * \param r Radius of the tube - * \param segments Number of segments used to render the tube - */ - void computeTube (sm::vec start, sm::vec end, - std::array colStart, std::array colEnd, - float r = 1.0f, int segments = 12) - { - this->computeFlaredTube (start, end, colStart, colEnd, r, r, segments); - } - - /*! - * Compute a tube. This version requires unit vectors for orientation of the - * tube end faces/vertices (useful for graph markers). The other version uses a - * randomly chosen vector to do this. - * - * Create a tube from \a start to \a end, with radius \a r and a colour which - * transitions from the colour \a colStart to \a colEnd. - * - * \param start The start of the tube - * \param end The end of the tube - * \param _ux a vector in the x axis direction for the end face - * \param _uy a vector in the y axis direction. _ux ^ _uy gives the end cap normal - * \param colStart The tube starting colour - * \param colEnd The tube's ending colour - * \param r Radius of the tube - * \param segments Number of segments used to render the tube - * \param rotation A rotation in the _ux/_uy plane to orient the vertices of the - * tube. Useful if this is to be a short tube used as a graph marker. - * \param bb If true, write into the bounding box arrays, not the main ones - */ - void computeTube (sm::vec start, sm::vec end, - sm::vec _ux, sm::vec _uy, - std::array colStart, std::array colEnd, - float r = 1.0f, int segments = 12, float rotation = 0.0f, bool bb = false) - { - // The vector from start to end defines direction of the tube - sm::vec vstart = start; - sm::vec vend = end; - - // v is a face normal - sm::vec v = _ux.cross(_uy); - v.renormalize(); - - // If bounding box, populate different buffers: - std::vector& vp = bb ? this->vpos_bb : this->vertexPositions; - std::vector& vn = bb ? this->vnorm_bb : this->vertexNormals; - std::vector& vc = bb ? this->vcol_bb : this->vertexColors; - std::vector& idcs = bb ? this->indices_bb : this->indices; - GLuint& _idx = bb ? this->idx_bb : this->idx; - - // Push the central point of the start cap - this is at location vstart - this->vertex_push (vstart, vp); - this->vertex_push (-v, vn); - this->vertex_push (colStart, vc); - - // Start cap vertices (a triangle fan) - for (int j = 0; j < segments; j++) { - // t is the angle of the segment - float t = rotation + j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = _ux * std::sin(t) * r + _uy * std::cos(t) * r; - this->vertex_push (vstart+c, vp); - this->vertex_push (-v, vn); - this->vertex_push (colStart, vc); - } - - // Intermediate, near start cap. Normals point in direction c - for (int j = 0; j < segments; j++) { - float t = rotation + j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = _ux * std::sin(t) * r + _uy * std::cos(t) * r; - this->vertex_push (vstart+c, vp); - c.renormalize(); - this->vertex_push (c, vn); - this->vertex_push (colStart, vc); - } - - // Intermediate, near end cap. Normals point in direction c - for (int j = 0; j < segments; j++) { - float t = rotation + (float)j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = _ux * std::sin(t) * r + _uy * std::cos(t) * r; - this->vertex_push (vend+c, vp); - c.renormalize(); - this->vertex_push (c, vn); - this->vertex_push (colEnd, vc); - } - - // Bottom cap vertices - for (int j = 0; j < segments; j++) { - float t = rotation + (float)j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = _ux * std::sin(t) * r + _uy * std::cos(t) * r; - this->vertex_push (vend+c, vp); - this->vertex_push (v, vn); - this->vertex_push (colEnd, vc); - } - - // Bottom cap. Push centre vertex as the last vertex. - this->vertex_push (vend, vp); - this->vertex_push (v, vn); - this->vertex_push (colEnd, vc); - - // Number of vertices = segments * 4 + 2. - int nverts = (segments * 4) + 2; - - // After creating vertices, push all the indices. - GLuint capMiddle = _idx; - GLuint capStartIdx = _idx + 1u; - GLuint endMiddle = _idx + static_cast(nverts) - 1u; - GLuint endStartIdx = capStartIdx + (3u * segments); - - // Start cap indices - for (int j = 0; j < segments-1; j++) { - idcs.push_back (capMiddle); - idcs.push_back (capStartIdx + j); - idcs.push_back (capStartIdx + 1 + j); - } - // Last one - idcs.push_back (capMiddle); - idcs.push_back (capStartIdx + segments - 1); - idcs.push_back (capStartIdx); - - // Middle sections - for (int lsection = 0; lsection < 3; ++lsection) { - capStartIdx = _idx + 1 + lsection*segments; - endStartIdx = capStartIdx + segments; - for (int j = 0; j < segments; j++) { - idcs.push_back (capStartIdx + j); - if (j == (segments-1)) { - idcs.push_back (capStartIdx); - } else { - idcs.push_back (capStartIdx + 1 + j); - } - idcs.push_back (endStartIdx + j); - idcs.push_back (endStartIdx + j); - if (j == (segments-1)) { - idcs.push_back (endStartIdx); - } else { - idcs.push_back (endStartIdx + 1 + j); - } - if (j == (segments-1)) { - idcs.push_back (capStartIdx); - } else { - idcs.push_back (capStartIdx + j + 1); - } - } - } - - // bottom cap - for (int j = 0; j < segments-1; j++) { - idcs.push_back (endMiddle); - idcs.push_back (endStartIdx + j); - idcs.push_back (endStartIdx + 1 + j); - } - idcs.push_back (endMiddle); - idcs.push_back (endStartIdx + segments - 1); - idcs.push_back (endStartIdx); - - // Update idx - _idx += nverts; - } // end computeTube with ux/uy vectors for faces - - /*! - * A 'draw an arrow' primitive. This is a 3D, tubular arrow made of a tube and a cone. - * - * \param start Start coordinate of the arrow - * - * \param end End coordinate of the arrow - * - * \param clr The colour for the arrow - * - * \param tube_radius Radius of arrow shaft. If < 0, then set from (end-start).length() - * - * \param arrowhead_prop The proportion of the arrow length that the head should take up - * - * \param cone_radius Radisu of cone that make the arrow head. If < 0, then set from - * tube_radius - * - * \param shapesides How many facets to draw tube/cone with - */ - void computeArrow (const sm::vec& start, const sm::vec& end, - const std::array clr, - float tube_radius = -1.0f, - float arrowhead_prop = -1.0f, - float cone_radius = -1.0f, - const int shapesides = 18) - { - // The right way to draw an arrow. - sm::vec arrow_line = end - start; - float len = arrow_line.length(); - // Unless client code specifies, compute tube radius from length of arrow - if (tube_radius < 0.0f) { tube_radius = len / 40.0f; } - if (arrowhead_prop < 0.0f) { arrowhead_prop = 0.15f; } - if (cone_radius < 0.0f) { cone_radius = 1.75f * tube_radius; } - // We don't draw the full tube - sm::vec cone_start = arrow_line.shorten (len * arrowhead_prop); - cone_start += start; - this->computeTube (start, cone_start, clr, clr, tube_radius, shapesides); - float conelen = (end-cone_start).length(); - if (arrow_line.length() > conelen) { - this->computeCone (cone_start, end, 0.0f, clr, cone_radius, shapesides); - } - } - - /*! - * Create a flared tube from \a start to \a end, with radius \a r at the start and a colour - * which transitions from the colour \a colStart to \a colEnd. The radius of the end is - * determined by the given angle, flare, in radians. - * - * \param idx The index into the 'vertex array' - * \param start The start of the tube - * \param end The end of the tube - * \param colStart The tube starting colour - * \param colEnd The tube's ending colour - * \param r Radius of the tube - * \param segments Number of segments used to render the tube - * \param flare The angle, measured wrt the direction of the tube in radians, by which the - * tube 'flares' - */ - void computeFlaredTube (sm::vec start, sm::vec end, - std::array colStart, std::array colEnd, - float r = 1.0f, int segments = 12, float flare = 0.0f) - { - // Find the length of the tube - sm::vec v = end - start; - float l = v.length(); - // Compute end radius from the length and the flare angle: - float r_add = l * std::tan (std::abs(flare)) * (flare > 0.0f ? 1.0f : -1.0f); - float r_end = r + r_add; - // Now call into the other overload: - this->computeFlaredTube (start, end, colStart, colEnd, r, r_end, segments); - } - - /*! - * Create a flared tube from \a start to \a end, with radius \a r at the start and a colour - * which transitions from the colour \a colStart to \a colEnd. The radius of the end is - * r_end, given as a function argument. - * - * \param start The start of the tube - * \param end The end of the tube - * \param colStart The tube starting colour - * \param colEnd The tube's ending colour - * \param r Radius of the tube's start cap - * \param r_end radius of the end cap - * \param segments Number of segments used to render the tube - */ - void computeFlaredTube (sm::vec start, sm::vec end, - std::array colStart, std::array colEnd, - float r = 1.0f, float r_end = 1.0f, int segments = 12) - { - // The vector from start to end defines a vector and a plane. Find a - // 'circle' of points in that plane. - sm::vec vstart = start; - sm::vec vend = end; - sm::vec v = vend - vstart; - v.renormalize(); - - // circle in a plane defined by a point (v0 = vstart or vend) and a normal - // (v) can be found: Choose random vector vr. A vector inplane = vr ^ v. The - // unit in-plane vector is inplane.normalise. Can now use that vector in the - // plan to define a point on the circle. Note that this starting point on - // the circle is at a random position, which means that this version of - // computeTube is useful for tubes that have quite a few segments. - sm::vec rand_vec; - rand_vec.randomize(); - sm::vec inplane = rand_vec.cross(v); - inplane.renormalize(); - - // Now use parameterization of circle inplane = p1-x1 and - // c1(t) = ( (p1-x1).normalized std::sin(t) + v.normalized cross (p1-x1).normalized * std::cos(t) ) - // c1(t) = ( inplane std::sin(t) + v * inplane * std::cos(t) - sm::vec v_x_inplane = v.cross(inplane); - - // Push the central point of the start cap - this is at location vstart - this->vertex_push (vstart, this->vertexPositions); - this->vertex_push (-v, this->vertexNormals); - this->vertex_push (colStart, this->vertexColors); - - // Start cap vertices. Draw as a triangle fan, but record indices so that we - // only need a single call to glDrawElements. - for (int j = 0; j < segments; j++) { - // t is the angle of the segment - float t = j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = inplane * std::sin(t) * r + v_x_inplane * std::cos(t) * r; - this->vertex_push (vstart+c, this->vertexPositions); - this->vertex_push (-v, this->vertexNormals); - this->vertex_push (colStart, this->vertexColors); - } - - // Intermediate, near start cap. Normals point in direction c - for (int j = 0; j < segments; j++) { - float t = j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = inplane * std::sin(t) * r + v_x_inplane * std::cos(t) * r; - this->vertex_push (vstart+c, this->vertexPositions); - c.renormalize(); - this->vertex_push (c, this->vertexNormals); - this->vertex_push (colStart, this->vertexColors); - } - - // Intermediate, near end cap. Normals point in direction c - for (int j = 0; j < segments; j++) { - float t = (float)j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = inplane * std::sin(t) * r_end + v_x_inplane * std::cos(t) * r_end; - this->vertex_push (vend+c, this->vertexPositions); - c.renormalize(); - this->vertex_push (c, this->vertexNormals); - this->vertex_push (colEnd, this->vertexColors); - } - - // Bottom cap vertices - for (int j = 0; j < segments; j++) { - float t = (float)j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = inplane * std::sin(t) * r_end + v_x_inplane * std::cos(t) * r_end; - this->vertex_push (vend+c, this->vertexPositions); - this->vertex_push (v, this->vertexNormals); - this->vertex_push (colEnd, this->vertexColors); - } - - // Bottom cap. Push centre vertex as the last vertex. - this->vertex_push (vend, this->vertexPositions); - this->vertex_push (v, this->vertexNormals); - this->vertex_push (colEnd, this->vertexColors); - - // Note: number of vertices = segments * 4 + 2. - int nverts = (segments * 4) + 2; - - // After creating vertices, push all the indices. - GLuint capMiddle = this->idx; - GLuint capStartIdx = this->idx + 1u; - GLuint endMiddle = this->idx + static_cast(nverts) - 1u; - GLuint endStartIdx = capStartIdx + (3u * segments); - - // Start cap - for (int j = 0; j < segments-1; j++) { - this->indices.push_back (capMiddle); - this->indices.push_back (capStartIdx + j); - this->indices.push_back (capStartIdx + 1 + j); - } - // Last one - this->indices.push_back (capMiddle); - this->indices.push_back (capStartIdx + segments - 1); - this->indices.push_back (capStartIdx); - - // Middle sections - for (int lsection = 0; lsection < 3; ++lsection) { - capStartIdx = this->idx + 1 + lsection*segments; - endStartIdx = capStartIdx + segments; - // This does sides between start and end. I want to do this three times. - for (int j = 0; j < segments; j++) { - // Triangle 1 - this->indices.push_back (capStartIdx + j); - if (j == (segments-1)) { - this->indices.push_back (capStartIdx); - } else { - this->indices.push_back (capStartIdx + 1 + j); - } - this->indices.push_back (endStartIdx + j); - // Triangle 2 - this->indices.push_back (endStartIdx + j); - if (j == (segments-1)) { - this->indices.push_back (endStartIdx); - } else { - this->indices.push_back (endStartIdx + 1 + j); - } - if (j == (segments-1)) { - this->indices.push_back (capStartIdx); - } else { - this->indices.push_back (capStartIdx + j + 1); - } - } - } - - // Bottom cap - for (int j = 0; j < segments-1; j++) { - this->indices.push_back (endMiddle); - this->indices.push_back (endStartIdx + j); - this->indices.push_back (endStartIdx + 1 + j); - } - // Last one - this->indices.push_back (endMiddle); - this->indices.push_back (endStartIdx + segments - 1); - this->indices.push_back (endStartIdx); - - // Update idx - this->idx += nverts; - } // end computeFlaredTube with randomly initialized end vertices - - /*! - * Create an open (no end caps) flared tube from \a start to \a end, with radius - * \a r at the start and a colour which transitions from the colour \a colStart - * to \a colEnd. The radius of the end is r_end, given as a function argument. - * - * This has a normal vector for the start and end of the tube, so that the - * circles can be angled. - * - * \param start The start of the tube - * \param end The end of the tube - * \param colStart The tube starting colour - * \param colEnd The tube's ending colour - * \param n_start The normal of the start 'face' - * \param n_end The normal of the end 'face' - * - * \param z_start A vector pointing to the first vertex on the tube. allows - * orientation of tube faces for connected tubes (which is what this primitive - * is all about) - * - * \param r Radius of the tube's start circle - * \param r_end radius of the end circle - * \param segments Number of segments used to render the tube - */ - void computeOpenFlaredTube (sm::vec start, sm::vec end, - sm::vec n_start, sm::vec n_end, - std::array colStart, std::array colEnd, - float r = 1.0f, float r_end = 1.0f, int segments = 12) - { - // The vector from start to end defines a vector and a plane. Find a - // 'circle' of points in that plane. - sm::vec vstart = start; - sm::vec vend = end; - sm::vec v = vend - vstart; - v.renormalize(); - - // Two rotations about our face normals - sm::quaternion rotn_start (n_start, sm::mathconst::pi_over_2); - sm::quaternion rotn_end (-n_end, sm::mathconst::pi_over_2); - - sm::vec inplane = v.cross (n_start); - // The above is no good if n_start and v are colinear. In that case choose random inplane: - if (inplane.length() < std::numeric_limits::epsilon()) { - sm::vec rand_vec; - rand_vec.randomize(); - inplane = rand_vec.cross(v); - } - inplane.renormalize(); - - // inplane defines a plane, n_start defines a plane. Our first point is the - // intersection of the two planes and the circle of the end. - sm::vec v_x_inplane = n_start.cross (inplane);// rotn_start * inplane; - v_x_inplane.renormalize(); - - // If r == r_end we want a circular cross section tube (and not an elliptical cross section). - float r_mod = r / v_x_inplane.cross (v).length(); - - // Start ring of vertices. Normals point in direction c - // Now use parameterization of circle inplane = p1-x1 and - // c1(t) = ( (p1-x1).normalized std::sin(t) + v.normalized cross (p1-x1).normalized * std::cos(t) ) - // c1(t) = ( inplane std::sin(t) + v * inplane * std::cos(t) - for (int j = 0; j < segments; j++) { - float t = j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = inplane * std::sin(t) * r + v_x_inplane * std::cos(t) * r_mod; - this->vertex_push (vstart+c, this->vertexPositions); - c.renormalize(); - this->vertex_push (c, this->vertexNormals); - this->vertex_push (colStart, this->vertexColors); - } - - // end ring of vertices. Normals point in direction c - v_x_inplane = inplane.cross (n_end); - v_x_inplane.renormalize(); - r_mod = r_end / v_x_inplane.cross (v).length(); - - for (int j = 0; j < segments; j++) { - float t = (float)j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = inplane * std::sin(t) * r_end + v_x_inplane * std::cos(t) * r_mod; - this->vertex_push (vend+c, this->vertexPositions); - c.renormalize(); - this->vertex_push (c, this->vertexNormals); - this->vertex_push (colEnd, this->vertexColors); - } - - // Number of vertices - int nverts = (segments * 2); - - // After creating vertices, push all the indices. - GLuint sIdx = this->idx; - GLuint eIdx = sIdx + segments; - // This does sides between start and end - for (int j = 0; j < segments; j++) { - // Triangle 1 - this->indices.push_back (sIdx + j); - if (j == (segments-1)) { - this->indices.push_back (sIdx); - } else { - this->indices.push_back (sIdx + 1 + j); - } - this->indices.push_back (eIdx + j); - // Triangle 2 - this->indices.push_back (eIdx + j); - if (j == (segments-1)) { - this->indices.push_back (eIdx); - } else { - this->indices.push_back (eIdx + 1 + j); - } - if (j == (segments-1)) { - this->indices.push_back (sIdx); - } else { - this->indices.push_back (sIdx + j + 1); - } - } - - // Update idx - this->idx += nverts; - } // end computeOpenFlaredTube - - // An open, but un-flared tube with no end caps - void computeOpenTube (sm::vec start, sm::vec end, - sm::vec n_start, sm::vec n_end, - std::array colStart, std::array colEnd, - float r = 1.0f, int segments = 12) - { - this->computeOpenFlaredTube (start, end, n_start, n_end, colStart, colEnd, r, r, segments); - } - - - //! Compute a Quad from 4 arbitrary corners which must be ordered clockwise around the quad. - void computeFlatQuad (sm::vec c1, sm::vec c2, - sm::vec c3, sm::vec c4, - std::array col) - { - // v is the face normal - sm::vec u1 = c1-c2; - sm::vec u2 = c2-c3; - sm::vec v = u2.cross(u1); - v.renormalize(); - - // Push corner vertices - size_t vpsz = this->vertexPositions.size(); - this->vertexPositions.resize (vpsz + 12); - for (unsigned int i = 0; i < 3u; ++i) { this->vertexPositions[vpsz++] = c1[i]; } - for (unsigned int i = 0; i < 3u; ++i) { this->vertexPositions[vpsz++] = c2[i]; } - for (unsigned int i = 0; i < 3u; ++i) { this->vertexPositions[vpsz++] = c3[i]; } - for (unsigned int i = 0; i < 3u; ++i) { this->vertexPositions[vpsz++] = c4[i]; } - - // Colours/normals - size_t vcsz = this->vertexColors.size(); - size_t vnsz = this->vertexNormals.size(); - this->vertexColors.resize (vcsz + 12); - this->vertexNormals.resize (vnsz + 12); - for (unsigned int i = 0; i < 4u; ++i) { - for (unsigned int j = 0; j < 3u; ++j) { - this->vertexColors[vcsz++] = col[j]; - this->vertexNormals[vnsz++] = v[j]; - } - } - - size_t i0 = this->indices.size(); - this->indices.resize (i0 + 6, 0); - this->indices[i0++] = this->idx; - this->indices[i0++] = this->idx + 2; - this->indices[i0++] = this->idx + 1; - this->indices[i0++] = this->idx; - this->indices[i0++] = this->idx + 3; - this->indices[i0++] = this->idx + 2; - - this->idx += 4; - } - - /*! - * Compute a tube. This version requires unit vectors for orientation of the - * tube end faces/vertices (useful for graph markers). The other version uses a - * randomly chosen vector to do this. - * - * Create a tube from \a start to \a end, with radius \a r and a colour which - * transitions from the colour \a colStart to \a colEnd. - * - * \param idx The index into the 'vertex array' - * \param vstart The centre of the polygon - * \param _ux a vector in the x axis direction for the end face - * \param _uy a vector in the y axis direction - * \param col The polygon colour - * \param r Radius of the tube - * \param segments Number of segments used to render the tube - * \param rotation A rotation in the ux/uy plane to orient the vertices of the - * tube. Useful if this is to be a short tube used as a graph marker. - */ - void computeFlatPoly (sm::vec vstart, - sm::vec _ux, sm::vec _uy, - std::array col, - float r = 1.0f, int segments = 12, float rotation = 0.0f) - { - // v is a face normal - sm::vec v = _uy.cross(_ux); - v.renormalize(); - - // Push the central point of the start cap - this is at location vstart - this->vertex_push (vstart, this->vertexPositions); - this->vertex_push (-v, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - // Polygon vertices (a triangle fan) - for (int j = 0; j < segments; j++) { - // t is the angle of the segment - float t = rotation + j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = _ux * std::sin(t) * r + _uy * std::cos(t) * r; - this->vertex_push (vstart+c, this->vertexPositions); - this->vertex_push (-v, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - } - - // Number of vertices - int nverts = segments + 1; - - // After creating vertices, push all the indices. - GLuint capMiddle = this->idx; - GLuint capStartIdx = this->idx + 1; - - // Start cap indices - for (int j = 0; j < segments-1; j++) { - this->indices.push_back (capMiddle); - this->indices.push_back (capStartIdx + j); - this->indices.push_back (capStartIdx + 1 + j); - } - // Last one - this->indices.push_back (capMiddle); - this->indices.push_back (capStartIdx + segments - 1); - this->indices.push_back (capStartIdx); - - // Update idx - this->idx += nverts; - } // end computeFlatPloy with ux/uy vectors for faces - - /*! - * Make a ring of radius r, comprised of flat segments - * - * \param ro position of the centre of the ring - * \param rc The ring colour. - * \param r Radius of the ring - * \param t Thickness of the ring - * \param segments Number of tube segments used to render the ring - */ - void computeRing (sm::vec ro, std::array rc, float r = 1.0f, - float t = 0.1f, int segments = 12) - { - float r_in = r - (t * 0.5f); - float r_out = r + (t * 0.5f); - this->computeRingInOut (ro, rc, r_in, r_out, segments); - } - - /*! - * Make a ring of radius r, comprised of flat segments, specifying inner and outer radii - * - * \param ro position of the centre of the ring - * \param rc The ring colour. - * \param r_in Inner radius of the ring - * \param r_out Outer radius of the ring - * \param segments Number of tube segments used to render the ring - */ - void computeRingInOut (sm::vec ro, std::array rc, - float r_in = 1.0f, float r_out = 2.0f, int segments = 12) - { - for (int j = 0; j < segments; j++) { - float segment = sm::mathconst::two_pi * static_cast(j) / segments; - // x and y of inner point - float xin = r_in * std::cos (segment); - float yin = r_in * std::sin (segment); - float xout = r_out * std::cos (segment); - float yout = r_out * std::sin (segment); - int segjnext = (j + 1) % segments; - float segnext = sm::mathconst::two_pi * static_cast(segjnext) / segments; - float xin_n = r_in * std::cos (segnext); - float yin_n = r_in * std::sin (segnext); - float xout_n = r_out * std::cos (segnext); - float yout_n = r_out * std::sin (segnext); - - // Now draw a quad - sm::vec c4 = { xin, yin, 0.0f }; - sm::vec c3 = { xout, yout, 0.0f }; - sm::vec c2 = { xout_n, yout_n, 0.0f }; - sm::vec c1 = { xin_n, yin_n, 0.0f }; - this->computeFlatQuad (ro + c1, ro + c2, ro + c3, ro + c4, rc); - } - } - - /*! - * Sphere, geodesic polygon version. - * - * This function creates an object with exactly one OpenGL vertex per 'geometric - * vertex of the polyhedron'. That means that colouring this object must be - * achieved by colouring the vertices and faces cannot be coloured - * distinctly. Pass in a single colour for the initial object. To recolour, - * modify the content of vertexColors. - * - * \tparam F The type used for the polyhedron computation. Use float or double. - * - * \param so The sphere offset. Where to place this sphere... - * \param sc The sphere colour. - * \param r Radius of the sphere - * \param iterations how many iterations of the geodesic polygon algo to go - * through. Determines faces: - * - * For 0 iterations, get a geodesic with 20 faces *0 - * For 1 iterations, get a geodesic with 80 faces - * For 2 iterations, get a geodesic with 320 faces *1 - * For 3 iterations, get a geodesic with 1280 faces *2 - * For 4 iterations, get a geodesic with 5120 faces *3 - * For 5 iterations, get a geodesic with 20480 faces *4 - * For 6 iterations, get a geodesic with 81920 faces - * For 7 iterations, get a geodesic with 327680 faces - * For 8 iterations, get a geodesic with 1310720 faces - * For 9 iterations, get a geodesic with 5242880 faces - * - * *0: You'll get an icosahedron - * *1: decent graphical results - * *2: excellent graphical results - * *3: You can *just about* see a difference between 4 iterations and 3, but not - * between 4 and 5. - * *4: The iterations limit if F is float (you'll get a runtime error 'vertices - * has wrong size' for iterations>5) - * - * \return The number of vertices in the generated geodesic sphere - */ - template - int computeSphereGeo (sm::vec so, std::array sc, float r = 1.0f, int iterations = 2) - { - if (iterations < 0) { throw std::runtime_error ("computeSphereGeo: iterations must be positive"); } - // test if type F is float - if constexpr (std::is_same, float>::value == true) { - if (iterations > 5) { - throw std::runtime_error ("computeSphereGeo: For iterations > 5, F needs to be double precision"); - } - } else { - if (iterations > 10) { - throw std::runtime_error ("computeSphereGeo: This is an abitrary iterations limit (10 gives 20971520 faces)"); - } - } - // Note that we need double precision to compute higher iterations of the geodesic (iterations > 5) - sm::geometry::icosahedral_geodesic geo = sm::geometry::make_icosahedral_geodesic (iterations); - - // Now essentially copy geo into vertex buffers - for (auto v : geo.poly.vertices) { - this->vertex_push (v.as_float() * r + so, this->vertexPositions); - this->vertex_push (v.as_float(), this->vertexNormals); - this->vertex_push (sc, this->vertexColors); - } - for (auto f : geo.poly.faces) { - this->indices.push_back (this->idx + f[0]); - this->indices.push_back (this->idx + f[1]); - this->indices.push_back (this->idx + f[2]); - } - // idx is the *vertex index* and should be incremented by the number of vertices in the polyhedron - int n_verts = static_cast(geo.poly.vertices.size()); - this->idx += n_verts; - - return n_verts; - } - - /*! - * Sphere, geodesic polygon version with coloured faces - * - * To colour the faces of this polyhedron, update this->vertexColors (for an - * example see mplot::GeodesicVisual). To make faces distinctly colourizable, we - * have to generate 3 OpenGL vertices for each of the geometric vertices in the - * polyhedron. - * - * \tparam F The type used for the polyhedron computation. Use float or double. - * - * \param so The sphere offset. Where to place this sphere... - * \param sc The default colour - * \param r Radius of the sphere - * \param iterations how many iterations of the geodesic polygon algo to go - * through. Determines number of faces - */ - template - int computeSphereGeoFaces (sm::vec so, std::array sc, float r = 1.0f, int iterations = 2) - { - if (iterations < 0) { throw std::runtime_error ("computeSphereGeo: iterations must be positive"); } - // test if type F is float - if constexpr (std::is_same, float>::value == true) { - if (iterations > 5) { - throw std::runtime_error ("computeSphereGeo: For iterations > 5, F needs to be double precision"); - } - } else { - if (iterations > 10) { - throw std::runtime_error ("computeSphereGeo: This is an abitrary iterations limit (10 gives 20971520 faces)"); - } - } - // Note that we need double precision to compute higher iterations of the geodesic (iterations > 5) - sm::geometry::icosahedral_geodesic geo = sm::geometry::make_icosahedral_geodesic (iterations); - int n_faces = static_cast(geo.poly.faces.size()); - - for (int i = 0; i < n_faces; ++i) { // For each face in the geodesic... - sm::vec norm = { F{0}, F{0}, F{0} }; - for (auto vtx : geo.poly.faces[i]) { // For each vertex in face... - norm += geo.poly.vertices[vtx]; // Add to the face norm - this->vertex_push (geo.poly.vertices[vtx].as_float() * r + so, this->vertexPositions); - } - sm::vec nf = (norm / F{3}).as_float(); - for (int j = 0; j < 3; ++j) { // Faces all have size 3 - this->vertex_push (nf, this->vertexNormals); - this->vertex_push (sc, this->vertexColors); // A default colour - this->indices.push_back (this->idx + (3 * i) + j); // indices is vertex index - } - } - // An index for each vertex of each face. - this->idx += 3 * n_faces; - - return n_faces; - } - - //! Fast computeSphereGeo, which uses constexpr make_icosahedral_geodesic. The - //! resulting vertices and faces are NOT in any kind of order, but ok for - //! plotting, e.g. scatter graph spheres. - template - int computeSphereGeoFast (sm::vec so, std::array sc, float r = 1.0f) - { - // test if type F is float - if constexpr (std::is_same, float>::value == true) { - static_assert (iterations <= 5, "computeSphereGeoFast: For iterations > 5, F needs to be double precision"); - } else { - static_assert (iterations <= 10, "computeSphereGeoFast: This is an abitrary iterations limit (10 gives 20971520 faces)"); - } - // Note that we need double precision to compute higher iterations of the geodesic (iterations > 5) - constexpr sm::geometry_ce::icosahedral_geodesic geo = sm::geometry_ce::make_icosahedral_geodesic(); - - // Now essentially copy geo into vertex buffers - for (auto v : geo.poly.vertices) { - this->vertex_push (v.as_float() * r + so, this->vertexPositions); - this->vertex_push (v.as_float(), this->vertexNormals); - this->vertex_push (sc, this->vertexColors); - } - for (auto f : geo.poly.faces) { - this->indices.push_back (this->idx + f[0]); - this->indices.push_back (this->idx + f[1]); - this->indices.push_back (this->idx + f[2]); - } - // idx is the *vertex index* and should be incremented by the number of vertices in the polyhedron - int n_verts = static_cast(geo.poly.vertices.size()); - this->idx += n_verts; - - return n_verts; - } - - /*! - * Sphere, 1 colour version. - * - * Code for creating a sphere as part of this model. I'll use a sphere at the centre of the arrows. - * - * \param so The sphere offset. Where to place this sphere... - * \param sc The sphere colour. - * \param r Radius of the sphere - * \param rings Number of rings used to render the sphere - * \param segments Number of segments used to render the sphere - * - * Number of faces should be (2 + rings) * segments - */ - void computeSphere (sm::vec so, std::array sc, - float r = 1.0f, int rings = 10, int segments = 12) - { - // First cap, draw as a triangle fan, but record indices so that - // we only need a single call to glDrawElements. - float rings0 = -sm::mathconst::pi_over_2; - float _z0 = std::sin(rings0); - float z0 = r * _z0; - float r0 = std::cos(rings0); - float rings1 = sm::mathconst::pi * (-0.5f + 1.0f / rings); - float _z1 = std::sin(rings1); - float z1 = r * _z1; - float r1 = std::cos(rings1); - // Push the central point - this->vertex_push (so[0]+0.0f, so[1]+0.0f, so[2]+z0, this->vertexPositions); - this->vertex_push (0.0f, 0.0f, -1.0f, this->vertexNormals); - this->vertex_push (sc, this->vertexColors); - - GLuint capMiddle = this->idx++; - GLuint ringStartIdx = this->idx; - GLuint lastRingStartIdx = this->idx; - - bool firstseg = true; - for (int j = 0; j < segments; j++) { - float segment = sm::mathconst::two_pi * static_cast(j) / segments; - float x = std::cos(segment); - float y = std::sin(segment); - - float _x1 = x*r1; - float x1 = _x1*r; - float _y1 = y*r1; - float y1 = _y1*r; - - this->vertex_push (so[0]+x1, so[1]+y1, so[2]+z1, this->vertexPositions); - this->vertex_push (_x1, _y1, _z1, this->vertexNormals); - this->vertex_push (sc, this->vertexColors); - - if (!firstseg) { - this->indices.push_back (capMiddle); - this->indices.push_back (this->idx-1); - this->indices.push_back (this->idx++); - } else { - this->idx++; - firstseg = false; - } - } - this->indices.push_back (capMiddle); - this->indices.push_back (this->idx-1); - this->indices.push_back (capMiddle+1); - - // Now add the triangles around the rings - for (int i = 2; i < rings; i++) { - - rings0 = sm::mathconst::pi * (-0.5f + static_cast(i) / rings); - _z0 = std::sin(rings0); - z0 = r * _z0; - r0 = std::cos(rings0); - - for (int j = 0; j < segments; j++) { - - // "current" segment - float segment = sm::mathconst::two_pi * static_cast(j) / segments; - float x = std::cos(segment); - float y = std::sin(segment); - - // One vertex per segment - float _x0 = x*r0; - float x0 = _x0*r; - float _y0 = y*r0; - float y0 = _y0*r; - - // NB: Only add ONE vertex per segment. ALREADY have the first ring! - this->vertex_push (so[0]+x0, so[1]+y0, so[2]+z0, this->vertexPositions); - // The vertex normal of a vertex that makes up a sphere is - // just a normal vector in the direction of the vertex. - this->vertex_push (_x0, _y0, _z0, this->vertexNormals); - this->vertex_push (sc, this->vertexColors); - - if (j == segments - 1) { - // Last vertex is back to the start - this->indices.push_back (ringStartIdx++); - this->indices.push_back (this->idx); - this->indices.push_back (lastRingStartIdx); - this->indices.push_back (lastRingStartIdx); - this->indices.push_back (this->idx++); - this->indices.push_back (lastRingStartIdx+segments); - } else { - this->indices.push_back (ringStartIdx++); - this->indices.push_back (this->idx); - this->indices.push_back (ringStartIdx); - this->indices.push_back (ringStartIdx); - this->indices.push_back (this->idx++); - this->indices.push_back (this->idx); - } - } - lastRingStartIdx += segments; - } - - // bottom cap - rings0 = sm::mathconst::pi_over_2; - _z0 = std::sin(rings0); - z0 = r * _z0; - r0 = std::cos(rings0); - // Push the central point of the bottom cap - this->vertex_push (so[0]+0.0f, so[1]+0.0f, so[2]+z0, this->vertexPositions); - this->vertex_push (0.0f, 0.0f, 1.0f, this->vertexNormals); - this->vertex_push (sc, this->vertexColors); - capMiddle = this->idx++; - firstseg = true; - // No more vertices to push, just do the indices for the bottom cap - ringStartIdx = lastRingStartIdx; - for (int j = 0; j < segments; j++) { - if (j != segments - 1) { - this->indices.push_back (capMiddle); - this->indices.push_back (ringStartIdx++); - this->indices.push_back (ringStartIdx); - } else { - // Last segment - this->indices.push_back (capMiddle); - this->indices.push_back (ringStartIdx); - this->indices.push_back (lastRingStartIdx); - } - } - } // end of sphere calculation - - /*! - * Sphere, two colour version. - * - * Code for creating a sphere as part of this model. I'll use a sphere at the - * centre of the arrows. - * - * \param so The sphere offset. Where to place this sphere... - * \param sc The sphere colour. - * \param sc2 The sphere's second colour - used for cap and first ring - * \param r Radius of the sphere - * \param rings Number of rings used to render the sphere - * \param segments Number of segments used to render the sphere - */ - void computeSphere (sm::vec so, std::array sc, std::array sc2, - float r = 1.0f, int rings = 10, int segments = 12) - { - // First cap, draw as a triangle fan, but record indices so that - // we only need a single call to glDrawElements. - float rings0 = -sm::mathconst::pi_over_2; - float _z0 = std::sin(rings0); - float z0 = r * _z0; - float r0 = std::cos(rings0); - float rings1 = sm::mathconst::pi * (-0.5f + 1.0f / rings); - float _z1 = std::sin(rings1); - float z1 = r * _z1; - float r1 = std::cos(rings1); - // Push the central point - this->vertex_push (so[0]+0.0f, so[1]+0.0f, so[2]+z0, this->vertexPositions); - this->vertex_push (0.0f, 0.0f, -1.0f, this->vertexNormals); - this->vertex_push (sc2, this->vertexColors); - - GLuint capMiddle = this->idx++; - GLuint ringStartIdx = this->idx; - GLuint lastRingStartIdx = this->idx; - - bool firstseg = true; - for (int j = 0; j < segments; j++) { - float segment = sm::mathconst::two_pi * static_cast(j) / segments; - float x = std::cos(segment); - float y = std::sin(segment); - - float _x1 = x*r1; - float x1 = _x1*r; - float _y1 = y*r1; - float y1 = _y1*r; - - this->vertex_push (so[0]+x1, so[1]+y1, so[2]+z1, this->vertexPositions); - this->vertex_push (_x1, _y1, _z1, this->vertexNormals); - this->vertex_push (sc2, this->vertexColors); - - if (!firstseg) { - this->indices.push_back (capMiddle); - this->indices.push_back (this->idx-1); - this->indices.push_back (this->idx++); - } else { - this->idx++; - firstseg = false; - } - } - this->indices.push_back (capMiddle); - this->indices.push_back (this->idx-1); - this->indices.push_back (capMiddle+1); - - // Now add the triangles around the rings - for (int i = 2; i < rings; i++) { - - rings0 = sm::mathconst::pi * (-0.5f + static_cast(i) / rings); - _z0 = std::sin(rings0); - z0 = r * _z0; - r0 = std::cos(rings0); - - for (int j = 0; j < segments; j++) { - - // "current" segment - float segment = sm::mathconst::two_pi * static_cast(j) / segments; - float x = std::cos(segment); - float y = std::sin(segment); - - // One vertex per segment - float _x0 = x*r0; - float x0 = _x0*r; - float _y0 = y*r0; - float y0 = _y0*r; - - // NB: Only add ONE vertex per segment. ALREADY have the first ring! - this->vertex_push (so[0]+x0, so[1]+y0, so[2]+z0, this->vertexPositions); - // The vertex normal of a vertex that makes up a sphere is - // just a normal vector in the direction of the vertex. - this->vertex_push (_x0, _y0, _z0, this->vertexNormals); - if (i == 2 || i > (rings-2)) { - this->vertex_push (sc2, this->vertexColors); - } else { - this->vertex_push (sc, this->vertexColors); - } - if (j == segments - 1) { - // Last vertex is back to the start - this->indices.push_back (ringStartIdx++); - this->indices.push_back (this->idx); - this->indices.push_back (lastRingStartIdx); - this->indices.push_back (lastRingStartIdx); - this->indices.push_back (this->idx++); - this->indices.push_back (lastRingStartIdx+segments); - } else { - this->indices.push_back (ringStartIdx++); - this->indices.push_back (this->idx); - this->indices.push_back (ringStartIdx); - this->indices.push_back (ringStartIdx); - this->indices.push_back (this->idx++); - this->indices.push_back (this->idx); - } - } - lastRingStartIdx += segments; - } - - // bottom cap - rings0 = sm::mathconst::pi_over_2; - _z0 = std::sin(rings0); - z0 = r * _z0; - r0 = std::cos(rings0); - // Push the central point of the bottom cap - this->vertex_push (so[0]+0.0f, so[1]+0.0f, so[2]+z0, this->vertexPositions); - this->vertex_push (0.0f, 0.0f, 1.0f, this->vertexNormals); - this->vertex_push (sc2, this->vertexColors); - capMiddle = this->idx++; - firstseg = true; - // No more vertices to push, just do the indices for the bottom cap - ringStartIdx = lastRingStartIdx; - for (int j = 0; j < segments; j++) { - if (j != segments - 1) { - this->indices.push_back (capMiddle); - this->indices.push_back (ringStartIdx++); - this->indices.push_back (ringStartIdx); - } else { - // Last segment - this->indices.push_back (capMiddle); - this->indices.push_back (ringStartIdx); - this->indices.push_back (lastRingStartIdx); - } - } - } - - /*! - * Compute an ellipsoid surface of the form x*x/a*a + y*y/b*b + z*z/c*c = 1 - * - * so is the offset position for the ellipsoid - * - * sc is the colour at one end of the z axis - * - * sc2 is the colour at the other end - * - * abc are the three ellipsoid parameters - * - * rings is the number of rings along the z axis - * - * segments is the number of segments in each ring along the z axis - * - * tr transform matrix to apply to each point in the ellipse (applied before so is applied - * as a transform) - */ - void computeEllipsoid (sm::vec so, - std::array sc, - std::array sc2, - sm::vec abc, - int rings = 10, int segments = 12, - sm::mat tr = sm::mat{}) - { - // We have two angular parameters t and t2. t in range 0-2pi and t2 in range 0-pi. t - // gives the 'xy' ellipse; t2 gives the change in size of the xy ellipse as the z axis - // is traversed. - float t = 0.0f; - float t2 = 0.0f; - // used computing normals - sm::vec two_over_abcsq = 2.0f / abc.sq(); - // Holding the coordinates of each point on the ellipsoid as we compute it - sm::vec p = {}; - // The normal vector - sm::vec n = {}; - - // sm::vec versions of the colours - sm::vec _sc = {}; - _sc.set_from (sc); - sm::vec _sc2 = {}; - _sc2.set_from (sc2); - - // Push the central point - p = { 0, 0, abc[2] }; - this->vertex_push (so + (tr * p).less_one_dim(), this->vertexPositions); - n = { 0, 0, 1 }; - this->vertex_push (n, this->vertexNormals); - this->vertex_push (_sc, this->vertexColors); - - GLuint capMiddle = this->idx++; - GLuint ringStartIdx = this->idx; - GLuint lastRingStartIdx = this->idx; - - t2 = sm::mathconst::pi / rings; - p[2] = abc[2] * std::cos(t2); - - bool firstseg = true; - for (int j = 0; j < segments; j++) { - - t = sm::mathconst::two_pi * static_cast(j) / segments; - p[0] = abc[0] * std::cos(t) * std::sin(t2); - p[1] = abc[1] * std::sin(t) * std::sin(t2); - - sm::vec<> pp = (tr * p).less_one_dim(); - this->vertex_push (so + pp, this->vertexPositions); - - n = (tr * (p * two_over_abcsq)).less_one_dim(); - n.renormalize(); - this->vertex_push (n, this->vertexNormals); - - sm::vec sc_ring = _sc * (1.0f - 1.0f / rings) + _sc2 * 1.0f / rings; - this->vertex_push (sc_ring, this->vertexColors); - - if (!firstseg) { - this->indices.push_back (capMiddle); - this->indices.push_back (this->idx-1); - this->indices.push_back (this->idx++); - } else { - this->idx++; - firstseg = false; - } - } - this->indices.push_back (capMiddle); - this->indices.push_back (this->idx-1); - this->indices.push_back (capMiddle+1); - - // Now add the triangles around the rings - for (int i = 2; i < rings; i++) { - - t2 = sm::mathconst::pi * (static_cast(i) / rings); - p[2] = abc[2] * std::cos(t2); - - sm::vec sc_ring = _sc * (1.0f - static_cast(i) / rings) + _sc2 * static_cast(i) / rings; - - for (int j = 0; j < segments; j++) { - - // "current" segment - t = sm::mathconst::two_pi * static_cast(j) / segments; - p[0] = abc[0] * std::cos(t) * std::sin(t2); - p[1] = abc[1] * std::sin(t) * std::sin(t2); - - // NB: Only add ONE vertex per segment. ALREADY have the first ring! - sm::vec<> pp = (tr * p).less_one_dim(); - this->vertex_push (so + pp, this->vertexPositions); - // The vertex normal of a vertex that makes up a sphere is - // just a normal vector in the direction of the vertex. - n = (tr * (p * two_over_abcsq)).less_one_dim(); - n.renormalize(); - this->vertex_push (n, this->vertexNormals); - - this->vertex_push (sc_ring, this->vertexColors); - - if (j == segments - 1) { - // Last vertex is back to the start - this->indices.push_back (ringStartIdx++); - this->indices.push_back (this->idx); - this->indices.push_back (lastRingStartIdx); - this->indices.push_back (lastRingStartIdx); - this->indices.push_back (this->idx++); - this->indices.push_back (lastRingStartIdx+segments); - } else { - this->indices.push_back (ringStartIdx++); - this->indices.push_back (this->idx); - this->indices.push_back (ringStartIdx); - this->indices.push_back (ringStartIdx); - this->indices.push_back (this->idx++); - this->indices.push_back (this->idx); - } - } - lastRingStartIdx += segments; - } - - // bottom cap - - // Push the central point of the bottom cap - p = { 0, 0, -abc[2] }; - this->vertex_push (so + (tr * p).less_one_dim(), this->vertexPositions); - n = { 0, 0, -1 }; - this->vertex_push (n, this->vertexNormals); - this->vertex_push (_sc2, this->vertexColors); - capMiddle = this->idx++; - firstseg = true; - // No more vertices to push, just do the indices for the bottom cap - ringStartIdx = lastRingStartIdx; - for (int j = 0; j < segments; j++) { - if (j != segments - 1) { - this->indices.push_back (capMiddle); - this->indices.push_back (ringStartIdx++); - this->indices.push_back (ringStartIdx); - } else { - // Last segment - this->indices.push_back (capMiddle); - this->indices.push_back (ringStartIdx); - this->indices.push_back (lastRingStartIdx); - } - } - } - - /*! - * Compute vertices for an icosahedron. - */ - void computeIcosahedron (sm::vec centre, - std::array, 20> face_colours, - float r = 1.0f) // radius or side length? - { - sm::geometry::polyhedron ico = sm::geometry::icosahedron(); - - for (int j = 0; j < 20; ++j) { - // Compute the face normal - sm::vec norml = (ico.vertices[ico.faces[j][0]] + ico.vertices[ico.faces[j][1]] + ico.vertices[ico.faces[j][2]])/3.0f; - this->vertex_push (centre + (ico.vertices[ico.faces[j][0]] * r), this->vertexPositions); - this->vertex_push (centre + (ico.vertices[ico.faces[j][1]] * r), this->vertexPositions); - this->vertex_push (centre + (ico.vertices[ico.faces[j][2]] * r), this->vertexPositions); - for (int i = 0; i < 3; ++i) { - this->vertex_push (norml, this->vertexNormals); - this->vertex_push (face_colours[j], this->vertexColors); - } - // Indices... - this->indices.push_back (this->idx); - this->indices.push_back (this->idx+1); - this->indices.push_back (this->idx+2); - this->idx += 3; - } - } - - /*! - * Create a cone. - * - * \param centre The centre of the cone - would be the end of the line - * - * \param tip The tip of the cone - * - * \param ringoffset Move the ring forwards or backwards along the vector from - * \a centre to \a tip. This is positive or negative proportion of tip - centre. - * - * \param col The cone colour - * - * \param r Radius of the ring - * - * \param segments Number of segments used to render the tube - */ - void computeCone (sm::vec centre, - sm::vec tip, - float ringoffset, - std::array col, - float r = 1.0f, int segments = 12) - { - // Cone is drawn as a base ring around a centre-of-the-base vertex, an - // intermediate ring which is on the base ring, but has different normals, a - // 'ring' around the tip (with suitable normals) and a 'tip' vertex - - sm::vec vbase = centre; - sm::vec vtip = tip; - sm::vec v = vtip - vbase; - v.renormalize(); - - // circle in a plane defined by a point and a normal - sm::vec rand_vec; - rand_vec.randomize(); - sm::vec inplane = rand_vec.cross(v); - inplane.renormalize(); - sm::vec v_x_inplane = v.cross(inplane); - - // Push the central point of the start cap - this is at location vstart - this->vertex_push (vbase, this->vertexPositions); - this->vertex_push (-v, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - // Base ring with normals in direction -v - for (int j = 0; j < segments; j++) { - float t = j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = inplane * std::sin(t) * r + v_x_inplane * std::cos(t) * r; - // Subtract the vector which makes this circle - c = c + (v * ringoffset); - this->vertex_push (vbase+c, this->vertexPositions); - this->vertex_push (-v, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - } - - // Intermediate ring of vertices around/aligned with the base ring with normals in direction c - for (int j = 0; j < segments; j++) { - float t = j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = inplane * std::sin(t) * r + v_x_inplane * std::cos(t) * r; - c = c + (v * ringoffset); - this->vertex_push (vbase+c, this->vertexPositions); - c.renormalize(); - this->vertex_push (c, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - } - - // Intermediate ring of vertices around the tip with normals direction c - for (int j = 0; j < segments; j++) { - float t = j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = inplane * std::sin(t) * r + v_x_inplane * std::cos(t) * r; - c = c + (v * ringoffset); - this->vertex_push (vtip, this->vertexPositions); - c.renormalize(); - this->vertex_push (c, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - } - - // Push tip vertex as the last vertex, normal is in direction v - this->vertex_push (vtip, this->vertexPositions); - this->vertex_push (v, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - // Number of vertices = segments * 3 + 2. - int nverts = segments * 3 + 2; - - // After creating vertices, push all the indices. - GLuint capMiddle = this->idx; - GLuint capStartIdx = this->idx + 1; - GLuint endMiddle = this->idx + static_cast(nverts) - 1u; - GLuint endStartIdx = capStartIdx; - - // Base of the cone - for (int j = 0; j < segments-1; j++) { - this->indices.push_back (capMiddle); - this->indices.push_back (capStartIdx + j); - this->indices.push_back (capStartIdx + 1 + j); - } - // Last tri of base - this->indices.push_back (capMiddle); - this->indices.push_back (capStartIdx + segments - 1); - this->indices.push_back (capStartIdx); - - // Middle sections - for (int lsection = 0; lsection < 2; ++lsection) { - capStartIdx = this->idx + 1 + lsection*segments; - endStartIdx = capStartIdx + segments; - for (int j = 0; j < segments; j++) { - // Triangle 1: - this->indices.push_back (capStartIdx + j); - if (j == (segments-1)) { - this->indices.push_back (capStartIdx); - } else { - this->indices.push_back (capStartIdx + 1 + j); - } - this->indices.push_back (endStartIdx + j); - // Triangle 2: - this->indices.push_back (endStartIdx + j); - if (j == (segments-1)) { - this->indices.push_back (endStartIdx); - } else { - this->indices.push_back (endStartIdx + 1 + j); - } - if (j == (segments-1)) { - this->indices.push_back (capStartIdx); - } else { - this->indices.push_back (capStartIdx + j + 1); - } - } - } - - // tip - for (int j = 0; j < segments-1; j++) { - this->indices.push_back (endMiddle); - this->indices.push_back (endStartIdx + j); - this->indices.push_back (endStartIdx + 1 + j); - } - // Last triangle of tip - this->indices.push_back (endMiddle); - this->indices.push_back (endStartIdx + segments - 1); - this->indices.push_back (endStartIdx); - - // Update idx - this->idx += nverts; - } // end of cone calculation - - //! Compute a line with a single colour - void computeLine (sm::vec start, sm::vec end, - sm::vec _uz, - std::array col, - float w = 0.1f, float thickness = 0.01f, float shorten = 0.0f) - { - this->computeLine (start, end, _uz, col, col, w, thickness, shorten); - } - - /*! - * Create a line from \a start to \a end, with width \a w and a colour which - * transitions from the colour \a colStart to \a colEnd. The thickness of the - * line in the z direction is \a thickness - * - * \param start The start of the tube - * \param end The end of the tube - * \param _uz Dirn of z (up) axis for end face of line. Should be normalized. - * \param colStart The tube staring colour - * \param colEnd The tube's ending colour - * \param w width of line - * \param thickness The thickness/depth of the line in uy direction - * \param shorten An amount by which to shorten the length of the line at each end. - */ - void computeLine (sm::vec start, sm::vec end, - sm::vec _uz, - std::array colStart, std::array colEnd, - float w = 0.1f, float thickness = 0.01f, float shorten = 0.0f) - { - // There are always 8 segments for this line object, 2 at each of 4 corners - const int segments = 8; - - // The vector from start to end defines direction of the tube - sm::vec vstart = start; - sm::vec vend = end; - sm::vec v = vend - vstart; - v.renormalize(); - - // If shorten is not 0, then modify vstart and vend - if (shorten > 0.0f) { - vstart = start + v * shorten; - vend = end - v * shorten; - } - - // vv is normal to v and _uz - sm::vec vv = v.cross(_uz); - vv.renormalize(); - - // Push the central point of the start cap - this is at location vstart - this->vertex_push (vstart, this->vertexPositions); - this->vertex_push (-v, this->vertexNormals); - this->vertex_push (colStart, this->vertexColors); - - // Compute the 'face angles' that will give the correct width and thickness for the line - std::array angles; - float w_ = w * 0.5f; - float d_ = thickness * 0.5f; - float r = std::sqrt (w_ * w_ + d_ * d_); - angles[0] = std::acos (w_ / r); - angles[1] = angles[0]; - angles[2] = sm::mathconst::pi - angles[0]; - angles[3] = angles[2]; - angles[4] = sm::mathconst::pi + angles[0]; - angles[5] = angles[4]; - angles[6] = sm::mathconst::two_pi - angles[0]; - angles[7] = angles[6]; - // The normals for the vertices around the line - std::array, 8> norms = { vv, _uz, _uz, -vv, -vv, -_uz, -_uz, vv }; - - // Start cap vertices (a triangle fan) - for (int j = 0; j < segments; j++) { - sm::vec c = _uz * std::sin(angles[j]) * r + vv * std::cos(angles[j]) * r; - this->vertex_push (vstart+c, this->vertexPositions); - this->vertex_push (-v, this->vertexNormals); - this->vertex_push (colStart, this->vertexColors); - } - - // Intermediate, near start cap. Normals point outwards. Need Additional vertices - for (int j = 0; j < segments; j++) { - sm::vec c = _uz * std::sin(angles[j]) * r + vv * std::cos(angles[j]) * r; - this->vertex_push (vstart+c, this->vertexPositions); - this->vertex_push (norms[j], this->vertexNormals); - this->vertex_push (colStart, this->vertexColors); - } - - // Intermediate, near end cap. Normals point in direction c - for (int j = 0; j < segments; j++) { - sm::vec c = _uz * std::sin(angles[j]) * r + vv * std::cos(angles[j]) * r; - this->vertex_push (vend+c, this->vertexPositions); - this->vertex_push (norms[j], this->vertexNormals); - this->vertex_push (colEnd, this->vertexColors); - } - - // Bottom cap vertices - for (int j = 0; j < segments; j++) { - sm::vec c = _uz * std::sin(angles[j]) * r + vv * std::cos(angles[j]) * r; - this->vertex_push (vend+c, this->vertexPositions); - this->vertex_push (v, this->vertexNormals); - this->vertex_push (colEnd, this->vertexColors); - } - - // Bottom cap. Push centre vertex as the last vertex. - this->vertex_push (vend, this->vertexPositions); - this->vertex_push (v, this->vertexNormals); - this->vertex_push (colEnd, this->vertexColors); - - // Number of vertices = segments * 4 + 2. - int nverts = (segments * 4) + 2; - - // After creating vertices, push all the indices. - GLuint capMiddle = this->idx; - GLuint capStartIdx = this->idx + 1u; - GLuint endMiddle = this->idx + static_cast(nverts) - 1u; - GLuint endStartIdx = capStartIdx + (3u * segments); - - // Start cap indices - for (int j = 0; j < segments-1; j++) { - this->indices.push_back (capMiddle); - this->indices.push_back (capStartIdx + j); - this->indices.push_back (capStartIdx + 1 + j); - } - // Last one - this->indices.push_back (capMiddle); - this->indices.push_back (capStartIdx + segments - 1); - this->indices.push_back (capStartIdx); - - // Middle sections - for (int lsection = 0; lsection < 3; ++lsection) { - capStartIdx = this->idx + 1 + lsection*segments; - endStartIdx = capStartIdx + segments; - for (int j = 0; j < segments; j++) { - this->indices.push_back (capStartIdx + j); - if (j == (segments-1)) { - this->indices.push_back (capStartIdx); - } else { - this->indices.push_back (capStartIdx + 1 + j); - } - this->indices.push_back (endStartIdx + j); - this->indices.push_back (endStartIdx + j); - if (j == (segments-1)) { - this->indices.push_back (endStartIdx); - } else { - this->indices.push_back (endStartIdx + 1 + j); - } - if (j == (segments-1)) { - this->indices.push_back (capStartIdx); - } else { - this->indices.push_back (capStartIdx + j + 1); - } - } - } - - // bottom cap - for (int j = 0; j < segments-1; j++) { - this->indices.push_back (endMiddle); - this->indices.push_back (endStartIdx + j); - this->indices.push_back (endStartIdx + 1 + j); - } - this->indices.push_back (endMiddle); - this->indices.push_back (endStartIdx + segments - 1); - this->indices.push_back (endStartIdx); - - // Update idx - this->idx += nverts; - } // end computeLine - - // Like computeLine, but this line has no thickness. - void computeFlatLine (sm::vec start, sm::vec end, - sm::vec _uz, - std::array col, - float w = 0.1f, float shorten = 0.0f) - { - // The vector from start to end defines direction of the tube - sm::vec vstart = start; - sm::vec vend = end; - sm::vec v = vend - vstart; - v.renormalize(); - - // If shorten is not 0, then modify vstart and vend - if (shorten > 0.0f) { - vstart = start + v * shorten; - vend = end - v * shorten; - } - - // vv is normal to v and _uz - sm::vec vv = v.cross(_uz); - vv.renormalize(); - - // corners of the line, and the start angle is determined from vv and w - sm::vec ww = vv * w * 0.5f; - sm::vec c1 = vstart + ww; - sm::vec c2 = vstart - ww; - sm::vec c3 = vend - ww; - sm::vec c4 = vend + ww; - - this->vertex_push (c1, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - this->vertex_push (c2, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - this->vertex_push (c3, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - this->vertex_push (c4, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - // Number of vertices = segments * 4 + 2. - int nverts = 4; - - // After creating vertices, push all the indices. - this->indices.push_back (this->idx); - this->indices.push_back (this->idx+1); - this->indices.push_back (this->idx+2); - - this->indices.push_back (this->idx); - this->indices.push_back (this->idx+2); - this->indices.push_back (this->idx+3); - - // Update idx - this->idx += nverts; - - } // end computeFlatLine - - // Like computeFlatLine but with option to add rounded start/end caps (I lazily - // draw a whole circle around start/end to achieve this, rather than figuring - // out a semi-circle). - void computeFlatLineRnd (sm::vec start, sm::vec end, - sm::vec _uz, - std::array col, - float w = 0.1f, float shorten = 0.0f, bool startcaps = true, bool endcaps = true) - { - // The vector from start to end defines direction of the tube - sm::vec vstart = start; - sm::vec vend = end; - sm::vec v = vend - vstart; - v.renormalize(); - - // If shorten is not 0, then modify vstart and vend - if (shorten > 0.0f) { - vstart = start + v * shorten; - vend = end - v * shorten; - } - - // vv is normal to v and _uz - sm::vec vv = v.cross(_uz); - vv.renormalize(); - - // corners of the line, and the start angle is determined from vv and w - sm::vec ww = vv * w * 0.5f; - sm::vec c1 = vstart + ww; - sm::vec c2 = vstart - ww; - sm::vec c3 = vend - ww; - sm::vec c4 = vend + ww; - - int segments = 12; - float r = 0.5f * w; - unsigned int startvertices = 0u; - if (startcaps) { - // Push the central point of the start cap - this is at location vstart - this->vertex_push (vstart, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - ++startvertices; - // Start cap vertices (a triangle fan) - for (int j = 0; j < segments; j++) { - float t = j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = { std::sin(t) * r, std::cos(t) * r, 0.0f }; - this->vertex_push (vstart+c, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - ++startvertices; - } - } - - this->vertex_push (c1, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - this->vertex_push (c2, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - this->vertex_push (c3, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - this->vertex_push (c4, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - unsigned int endvertices = 0u; - if (endcaps) { - // Push the central point of the end cap - this is at location vend - this->vertex_push (vend, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - ++endvertices; - // End cap vertices (a triangle fan) - for (int j = 0; j < segments; j++) { - float t = j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = { std::sin(t) * r, std::cos(t) * r, 0.0f }; - this->vertex_push (vend+c, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - ++endvertices; - } - } - - // After creating vertices, push all the indices. - - if (startcaps) { // prolly startcaps, for flexibility - GLuint topcap = this->idx; - for (int j = 0; j < segments; j++) { - int inc1 = 1+j; - int inc2 = 1+((j+1)%segments); - this->indices.push_back (topcap); - this->indices.push_back (topcap+inc1); - this->indices.push_back (topcap+inc2); - } - this->idx += startvertices; - } - - // The line itself - this->indices.push_back (this->idx); - this->indices.push_back (this->idx+1); - this->indices.push_back (this->idx+2); - this->indices.push_back (this->idx); - this->indices.push_back (this->idx+2); - this->indices.push_back (this->idx+3); - // Update idx - this->idx += 4; - - if (endcaps) { - GLuint botcap = this->idx; - for (int j = 0; j < segments; j++) { - int inc1 = 1+j; - int inc2 = 1+((j+1)%segments); - this->indices.push_back (botcap); - this->indices.push_back (botcap+inc1); - this->indices.push_back (botcap+inc2); - } - this->idx += endvertices; - } - } // end computeFlatLine - - /*! - * Like computeFlatLine, but this line has no thickness and you can provide the - * previous and next data points so that this line, the previous line and the - * next line can line up perfectly without drawing a circular rounded 'end cap'! - * - * This code assumes that the coordinates prev, start, end, next all lie on a 2D - * plane normal to _uz. In fact, the 3D coordinates start, end, prev and next - * will all be projected onto the plane defined by _uz, so that they can be - * reduced to 2D coordinates. This then allows crossing points of lines to be - * computed. - * - * If you want to make a ribbon between points that do *not* lie on a 2D plane, - * you'll need to write another graphics primitive function. - */ - void computeFlatLine (sm::vec start, sm::vec end, - sm::vec prev, sm::vec next, - sm::vec _uz, - std::array col, - float w = 0.1f) - { - // Corner coordinates for this line section - sm::vec c1 = { 0.0f }; - sm::vec c2 = { 0.0f }; - sm::vec c3 = { 0.0f }; - sm::vec c4 = { 0.0f }; - - // Ensure _uz is a unit vector - sm::vec __uz = _uz; - __uz.renormalize(); - - // First find the rotation to make __uz into the actual unit z dirn - sm::quaternion rotn; - sm::vec basis_rotn_axis = __uz.cross (sm::vec<>::uz()); - if (basis_rotn_axis.length() > 0.0f) { - float basis_rotn_angle = __uz.angle (sm::vec<>::uz(), basis_rotn_axis); - rotn.rotate (basis_rotn_axis, basis_rotn_angle); - } // else nothing to do - basis rotn is null - - // Transform so that start is the origin - // sm::vec s_o = { 0.0f }; // by defn - sm::vec e_o = end - start; - sm::vec p_o = prev - start; - sm::vec n_o = next - start; - - // Apply basis rotation just to the end point. e_b: 'end point in rotated basis' - sm::vec e_b = rotn * e_o; - - // Use the vector from start to end as the in-plane x dirn. Do this AFTER - // first coord rotn. In other words: find the rotation about the new unit z - // direction to force the end point to be on the x axis - sm::vec plane_x = e_b; // - s_b but s_b is (0,0,0) by defn - plane_x.renormalize(); - sm::vec plane_y = sm::vec<>::uz().cross (plane_x); - plane_y.renormalize(); - // Find the in-plane coordinates in the rotated plane system - sm::vec e_p = { plane_x.dot (e_b), plane_y.dot (e_b), sm::vec<>::uz().dot (e_b) }; - - // One epsilon is exacting - if (std::abs(e_p[2]) > std::numeric_limits::epsilon()) { - throw std::runtime_error ("uz not orthogonal to the line start -> end?"); - } - - // From e_p and e_b (which should both be in a 2D plane) figure out what - // angle of rotation brings e_b into the x axis - float inplane_rotn_angle = e_b.angle (e_p, sm::vec<>::uz()); - sm::quaternion inplane_rotn (sm::vec<>::uz(), inplane_rotn_angle); - - // Apply the in-plane rotation to the basis rotation - rotn.premultiply (inplane_rotn); - - // Transform points - sm::vec p_p = rotn * p_o; - sm::vec n_p = rotn * n_o; - //vec s_p = rotn * s_o; // not necessary, s_p = (0,0,0) by defn - - // Line crossings time. - sm::vec c1_p = { 0.0f }; // 2D crossing coords that we're going to find - sm::vec c2_p = { 0.0f }; - sm::vec c3_p = e_p.less_one_dim(); - sm::vec c4_p = e_p.less_one_dim(); - - // 3 lines on each side. l_p, l_c (current) and l_n. Each has two ends. l_p_1, l_p_2 etc. - - // 'prev' 'cur' and 'next' vectors - sm::vec p_vec = (/*s_p*/ -p_p).less_one_dim(); - sm::vec c_vec = e_p.less_one_dim(); - sm::vec n_vec = (n_p - e_p).less_one_dim(); - - sm::vec p_ortho = (/*s_p*/ - p_p).cross (sm::vec<>::uz()).less_one_dim(); - p_ortho.renormalize(); - sm::vec c_ortho = (e_p /*- s_p*/).cross (sm::vec<>::uz()).less_one_dim(); - c_ortho.renormalize(); - sm::vec n_ortho = (n_p - e_p).cross (sm::vec<>::uz()).less_one_dim(); - n_ortho.renormalize(); - - const float hw = w / 2.0f; - - sm::vec l_p_1 = p_p.less_one_dim() + (p_ortho * hw) - p_vec; // makes it 3 times as long as the line. - sm::vec l_p_2 = /*s_p.less_one_dim() +*/ (p_ortho * hw) + p_vec; - sm::vec l_c_1 = /*s_p.less_one_dim() +*/ (c_ortho * hw) - c_vec; - sm::vec l_c_2 = e_p.less_one_dim() + (c_ortho * hw) + c_vec; - sm::vec l_n_1 = e_p.less_one_dim() + (n_ortho * hw) - n_vec; - sm::vec l_n_2 = n_p.less_one_dim() + (n_ortho * hw) + n_vec; - - std::bitset<2> isect = sm::geometry::segments_intersect (l_p_1, l_p_2, l_c_1, l_c_2); - if (isect.test(0) == true && isect.test(1) == false) { // test for intersection but not colinear - c1_p = sm::geometry::crossing_point (l_p_1, l_p_2, l_c_1, l_c_2); - } else if (isect.test(0) == true && isect.test(1) == true) { - c1_p = /*s_p.less_one_dim() +*/ (c_ortho * hw); - } else { // no intersection. prev could have been start - c1_p = /*s_p.less_one_dim() +*/ (c_ortho * hw); - } - isect = sm::geometry::segments_intersect (l_c_1, l_c_2, l_n_1, l_n_2); - if (isect.test(0) == true && isect.test(1) == false) { - c4_p = sm::geometry::crossing_point (l_c_1, l_c_2, l_n_1, l_n_2); - } else if (isect.test(0) == true && isect.test(1) == true) { - c4_p = e_p.less_one_dim() + (c_ortho * hw); - } else { // no intersection, prev could have been end - c4_p = e_p.less_one_dim() + (c_ortho * hw); - } - - // o for 'other side'. Could re-use vars in future version. Or just subtract (*_ortho * w) from each. - sm::vec o_l_p_1 = p_p.less_one_dim() - (p_ortho * hw) - p_vec; // makes it 3 times as long as the line. - sm::vec o_l_p_2 = /*s_p.less_one_dim()*/ - (p_ortho * hw) + p_vec; - sm::vec o_l_c_1 = /*s_p.less_one_dim()*/ - (c_ortho * hw) - c_vec; - sm::vec o_l_c_2 = e_p.less_one_dim() - (c_ortho * hw) + c_vec; - sm::vec o_l_n_1 = e_p.less_one_dim() - (n_ortho * hw) - n_vec; - sm::vec o_l_n_2 = n_p.less_one_dim() - (n_ortho * hw) + n_vec; - - isect = sm::geometry::segments_intersect (o_l_p_1, o_l_p_2, o_l_c_1, o_l_c_2); - if (isect.test(0) == true && isect.test(1) == false) { // test for intersection but not colinear - c2_p = sm::geometry::crossing_point (o_l_p_1, o_l_p_2, o_l_c_1, o_l_c_2); - } else if (isect.test(0) == true && isect.test(1) == true) { - c2_p = /*s_p.less_one_dim()*/ - (c_ortho * hw); - } else { // no intersection. prev could have been start - c2_p = /*s_p.less_one_dim()*/ - (c_ortho * hw); - } - - isect = sm::geometry::segments_intersect (o_l_c_1, o_l_c_2, o_l_n_1, o_l_n_2); - if (isect.test(0) == true && isect.test(1) == false) { - c3_p = sm::geometry::crossing_point (o_l_c_1, o_l_c_2, o_l_n_1, o_l_n_2); - } else if (isect.test(0) == true && isect.test(1) == true) { - c3_p = e_p.less_one_dim() - (c_ortho * hw); - } else { // no intersection. next could have been end - c3_p = e_p.less_one_dim() - (c_ortho * hw); - } - - // Transform and rotate back into c1-c4 - sm::quaternion rotn_inv = rotn.invert(); - c1 = rotn_inv * c1_p.plus_one_dim() + start; - c2 = rotn_inv * c2_p.plus_one_dim() + start; - c3 = rotn_inv * c3_p.plus_one_dim() + start; - c4 = rotn_inv * c4_p.plus_one_dim() + start; - - // Now create the vertices from these four corners, c1-c4 - this->vertex_push (c1, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - this->vertex_push (c2, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - this->vertex_push (c3, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - this->vertex_push (c4, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - this->indices.push_back (this->idx); - this->indices.push_back (this->idx+1); - this->indices.push_back (this->idx+2); - - this->indices.push_back (this->idx); - this->indices.push_back (this->idx+2); - this->indices.push_back (this->idx+3); - - // Update idx - this->idx += 4; - } // end computeFlatLine that joins perfectly - - //! Make a joined up line with previous. - void computeFlatLineP (sm::vec start, sm::vec end, - sm::vec prev, - sm::vec _uz, - std::array col, - float w = 0.1f) - { - this->computeFlatLine (start, end, prev, end, _uz, col, w); - } // end computeFlatLine that joins perfectly with prev - - //! Flat line, joining up with next - void computeFlatLineN (sm::vec start, sm::vec end, - sm::vec next, - sm::vec _uz, - std::array col, - float w = 0.1f) - { - this->computeFlatLine (start, end, start, next, _uz, col, w); - } - - // Like computeLine, but this line has no thickness and it's dashed. - // dashlen: the length of dashes - // gap prop: The proportion of dash length used for the gap - void computeFlatDashedLine (sm::vec start, sm::vec end, - sm::vec _uz, - std::array col, - float w = 0.1f, float shorten = 0.0f, - float dashlen = 0.1f, float gapprop = 0.3f) - { - if (dashlen == 0.0f) { return; } - - // The vector from start to end defines direction of the line - sm::vec vstart = start; - sm::vec vend = end; - - sm::vec v = vend - vstart; - float linelen = v.length(); - v.renormalize(); - - // If shorten is not 0, then modify vstart and vend - if (shorten > 0.0f) { - vstart = start + v * shorten; - vend = end - v * shorten; - linelen = v.length() - shorten * 2.0f; - } - - // vv is normal to v and _uz - sm::vec vv = v.cross(_uz); - vv.renormalize(); - - // Loop, creating the dashes - sm::vec dash_s = vstart; - sm::vec dash_e = dash_s + v * dashlen; - sm::vec dashes = dash_e - vstart; - - while (dashes.length() < linelen) { - - // corners of the line, and the start angle is determined from vv and w - sm::vec ww = vv * w * 0.5f; - sm::vec c1 = dash_s + ww; - sm::vec c2 = dash_s - ww; - sm::vec c3 = dash_e - ww; - sm::vec c4 = dash_e + ww; - - this->vertex_push (c1, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - this->vertex_push (c2, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - this->vertex_push (c3, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - this->vertex_push (c4, this->vertexPositions); - this->vertex_push (_uz, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - - // Number of vertices = segments * 4 + 2. - int nverts = 4; - - // After creating vertices, push all the indices. - this->indices.push_back (this->idx); - this->indices.push_back (this->idx+1); - this->indices.push_back (this->idx+2); - - this->indices.push_back (this->idx); - this->indices.push_back (this->idx+2); - this->indices.push_back (this->idx+3); - - // Update idx - this->idx += nverts; - - // Next dash - dash_s = dash_e + v * dashlen * gapprop; - dash_e = dash_s + v * dashlen; - dashes = dash_e - vstart; - } - - } // end computeFlatDashedLine - - // Compute a flat line circle outline - void computeFlatCircleLine (sm::vec centre, sm::vec norm, sm::vec inplane, float radius, - float linewidth, std::array col, int segments = 128) - { - inplane.renormalize(); - sm::vec norm_x_inplane = norm.cross(inplane); - - float half_lw = linewidth / 2.0f; - float r_in = radius - half_lw; - float r_out = radius + half_lw; - // Inner ring at radius radius-linewidth/2 with normals in direction norm; - // Outer ring at radius radius+linewidth/2 with normals also in direction norm - for (int j = 0; j < segments; j++) { - float t = j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c_in = inplane * std::sin(t) * r_in + norm_x_inplane * std::cos(t) * r_in; - this->vertex_push (centre+c_in, this->vertexPositions); - this->vertex_push (norm, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - sm::vec c_out = inplane * std::sin(t) * r_out + norm_x_inplane * std::cos(t) * r_out; - this->vertex_push (centre+c_out, this->vertexPositions); - this->vertex_push (norm, this->vertexNormals); - this->vertex_push (col, this->vertexColors); - } - // Added 2*segments vertices to vertexPositions - - // After creating vertices, push all the indices. - for (int j = 0; j < segments; j++) { - int jn = (segments + ((j+1) % segments)) % segments; - this->indices.push_back (this->idx+(2*j)); - this->indices.push_back (this->idx+(2*jn)); - this->indices.push_back (this->idx+(2*jn+1)); - this->indices.push_back (this->idx+(2*j)); - this->indices.push_back (this->idx+(2*jn+1)); - this->indices.push_back (this->idx+(2*j+1)); - } - this->idx += 2 * segments; // nverts - - } // end computeFlatCircleLine - - // Compute a flat line circle outline - void computeFlatCircleLine (sm::vec centre, sm::vec norm, float radius, - float linewidth, std::array col, int segments = 128) - { - // circle in a plane defined by a point (v0 = vstart or vend) and a normal - // (v) can be found: Choose random vector vr. A vector inplane = vr ^ v. The - // unit in-plane vector is inplane.normalise. Can now use that vector in the - // plan to define a point on the circle. Note that this starting point on - // the circle is at a random position, which means that this version of - // computeFlatCircleLine is useful for tubes that have quite a few segments. - sm::vec rand_vec; - rand_vec.randomize(); - sm::vec inplane = rand_vec.cross(norm); - // Sub call to the method that takes a normal vector AND an inplane vector: - this->computeFlatCircleLine (centre, norm, inplane, radius, linewidth, col, segments); - } - - // Compute triangles to form a true cuboid from 8 corners. - void computeCuboid (const std::array, 8>& v, const std::array& clr) - { - this->computeFlatQuad (v[0], v[1], v[2], v[3], clr); - this->computeFlatQuad (v[0], v[4], v[5], v[1], clr); - this->computeFlatQuad (v[1], v[5], v[6], v[2], clr); - this->computeFlatQuad (v[2], v[6], v[7], v[3], clr); - this->computeFlatQuad (v[3], v[7], v[4], v[0], clr); - this->computeFlatQuad (v[7], v[6], v[5], v[4], clr); - } - - // Compute a rhombus using the four defining coordinates. The coordinates are named as if - // they were the origin, x, y and z of a right-handed 3D coordinate system. These define three edges - void computeRhombus (const sm::vec& o, const sm::vec& x, const sm::vec& y, const sm::vec& z, - const std::array& clr) - { - // Edge vectors - sm::vec edge1 = x - o; - sm::vec edge2 = y - o; - sm::vec edge3 = z - o; - - // Compute the face normals - sm::vec _n1 = edge1.cross (edge2); - _n1.renormalize(); - sm::vec _n2 = edge2.cross (edge3); - _n2.renormalize(); - sm::vec _n3 = edge1.cross (edge3); - _n3.renormalize(); - - // Push positions and normals for 24 vertices to make up the rhombohedron; 4 for each face. - // Front face - this->vertex_push (o, this->vertexPositions); - this->vertex_push (o + edge1, this->vertexPositions); - this->vertex_push (o + edge3, this->vertexPositions); - this->vertex_push (o + edge1 + edge3, this->vertexPositions); - for (unsigned short i = 0U; i < 4U; ++i) { this->vertex_push (_n3, this->vertexNormals); } - // Top face - this->vertex_push (o + edge3, this->vertexPositions); - this->vertex_push (o + edge1 + edge3, this->vertexPositions); - this->vertex_push (o + edge2 + edge3, this->vertexPositions); - this->vertex_push (o + edge2 + edge1 + edge3, this->vertexPositions); - for (unsigned short i = 0U; i < 4U; ++i) { this->vertex_push (_n1, this->vertexNormals); } - // Back face - this->vertex_push (o + edge2 + edge3, this->vertexPositions); - this->vertex_push (o + edge2 + edge1 + edge3, this->vertexPositions); - this->vertex_push (o + edge2, this->vertexPositions); - this->vertex_push (o + edge2 + edge1, this->vertexPositions); - for (unsigned short i = 0U; i < 4U; ++i) { this->vertex_push (-_n3, this->vertexNormals); } - // Bottom face - this->vertex_push (o + edge2, this->vertexPositions); - this->vertex_push (o + edge2 + edge1, this->vertexPositions); - this->vertex_push (o, this->vertexPositions); - this->vertex_push (o + edge1, this->vertexPositions); - for (unsigned short i = 0U; i < 4U; ++i) { this->vertex_push (-_n1, this->vertexNormals); } - // Left face - this->vertex_push (o + edge2, this->vertexPositions); - this->vertex_push (o, this->vertexPositions); - this->vertex_push (o + edge2 + edge3, this->vertexPositions); - this->vertex_push (o + edge3, this->vertexPositions); - for (unsigned short i = 0U; i < 4U; ++i) { this->vertex_push (-_n2, this->vertexNormals); } - // Right face - this->vertex_push (o + edge1, this->vertexPositions); - this->vertex_push (o + edge1 + edge2, this->vertexPositions); - this->vertex_push (o + edge1 + edge3, this->vertexPositions); - this->vertex_push (o + edge1 + edge2 + edge3, this->vertexPositions); - for (unsigned short i = 0U; i < 4U; ++i) { this->vertex_push (_n2, this->vertexNormals); } - - // Vertex colours are all the same - for (unsigned short i = 0U; i < 24U; ++i) { this->vertex_push (clr, this->vertexColors); } - - // Indices for 6 faces - for (unsigned short i = 0U; i < 6U; ++i) { - this->indices.push_back (this->idx++); - this->indices.push_back (this->idx++); - this->indices.push_back (this->idx--); - this->indices.push_back (this->idx++); - this->indices.push_back (this->idx++); - this->indices.push_back (this->idx++); - } - } // computeCuboid - - // Compute a rectangular cuboid of width (in x), height (in y) and depth (in z). - void computeRectCuboid (const sm::vec& o, const float wx, const float hy, const float dz, - const std::array& clr) - { - sm::vec px = o + sm::vec{wx, 0, 0}; - sm::vec py = o + sm::vec{0, hy, 0}; - sm::vec pz = o + sm::vec{0, 0, dz}; - this->computeRhombus (o, px, py, pz, clr); - } - - // Compute the bounding box frame - void computeBoundingBox() - { - // Draw a frame of tubes from bb.min to bb.max - const float& x0 = this->bb.min[0]; - const float& y0 = this->bb.min[1]; - const float& z0 = this->bb.min[2]; - - const float& x1 = this->bb.max[0]; - const float& y1 = this->bb.max[1]; - const float& z1 = this->bb.max[2]; - - const sm::vec& c0 = this->bb.min; - sm::vec c1 = { x1, y0, z0 }; - sm::vec c2 = { x1, y1, z0 }; - sm::vec c3 = { x0, y1, z0 }; - - sm::vec c4 = { x0, y0, z1 }; - sm::vec c5 = { x1, y0, z1 }; - const sm::vec& c6 = this->bb.max; - sm::vec c7 = { x0, y1, z1 }; - - constexpr int segs = 4; - constexpr float zrot = 0.0f; - auto cl = this->colour_bb; - - // Frame tube radius - float r = this->bb.span().length() / 500.0f; - - // Base - this->computeTube (c0, c1, sm::vec::uy(), sm::vec::uz(), cl, cl, r, segs, zrot, true); - this->computeTube (c1, c2, -sm::vec::ux(), sm::vec::uz(), cl, cl, r, segs, zrot, true); - this->computeTube (c2, c3, -sm::vec::uy(), sm::vec::uz(), cl, cl, r, segs, zrot, true); - this->computeTube (c3, c0, sm::vec::ux(), sm::vec::uz(), cl, cl, r, segs, zrot, true); - // Top - this->computeTube (c4, c5, sm::vec::uy(), sm::vec::uz(), cl, cl, r, segs, zrot, true); - this->computeTube (c5, c6, -sm::vec::ux(), sm::vec::uz(), cl, cl, r, segs, zrot, true); - this->computeTube (c6, c7, -sm::vec::uy(), sm::vec::uz(), cl, cl, r, segs, zrot, true); - this->computeTube (c7, c4, sm::vec::ux(), sm::vec::uz(), cl, cl, r, segs, zrot, true); - // Sides - this->computeTube (c0, c4, sm::vec::uy(), -sm::vec::ux(), cl, cl, r, segs, zrot, true); - this->computeTube (c1, c5, sm::vec::uy(), -sm::vec::ux(), cl, cl, r, segs, zrot, true); - this->computeTube (c2, c6, sm::vec::uy(), -sm::vec::ux(), cl, cl, r, segs, zrot, true); - this->computeTube (c3, c7, sm::vec::uy(), -sm::vec::ux(), cl, cl, r, segs, zrot, true); - } - }; - -} // namespace mplot diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index f63786e3..537eae46 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -24,12 +24,32 @@ module; # include #endif // GL headers +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include #include #include #include - +#include #include +#include + +#include + +#include + +#include + // Use Lode Vandevenne's PNG encoder #define LODEPNG_NO_COMPILE_DECODER 1 #define LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS 1 @@ -41,10 +61,9 @@ export module mplot.core:visualownable; import :visualcommon; import :visualresources; -import :visualtextmodel; -import :textgeometry; -import :textfeatures; -import :visualbase; +import mplot.visualtextmodel; +import mplot.textgeometry; +import mplot.textfeatures; import :coordarrows; import sm.vec; @@ -58,6 +77,103 @@ export namespace mplot constexpr double retinaScale = 1; // Qt has devicePixelRatio() to get retinaScale. #endif + //! Here are our boolean state flags + enum class visual_state : uint32_t + { + readyToFinish, + //! paused can be set true so that pauseOpen() can be used to display the window mid-simulation + paused, + //! If you set this to true, then the mouse movements won't change scenetrans or rotation. + sceneLocked, + //! When true, cursor movements induce rotation of scene + rotateMode, + //! When true, rotations about the third axis are possible. + rotateModMode, + //! When true, cursor movements induce translation of scene + translateMode, + //! We are scrolling (and so we will need to zero scenetrans_delta after enacting the change) + scrolling, + //! True means that at least one of our VisualModels is an instanced rendering model + haveInstanced, + //! When true, the instanced data SSBO needs to be copied to the GPU + instancedNeedsUpdate, + //! Left mouse button is down + mouseButtonLeftPressed, + //! Right mouse button is down + mouseButtonRightPressed + }; + + //! Boolean options - similar to state, but more likely to be modified by client code + enum class visual_options : uint32_t + { + //! Set true to disable the 'X' button on the Window from exiting the program + preventWindowCloseWithButton, + //! Set to true to show the coordinate arrows + showCoordArrows, + //! If true, then place the coordinate arrows at the origin of the scene, rather than offset. + coordArrowsInScene, + //! Show user frame of reference (for debug) + showUserFrame, + //! Set to true to show the title text within the scene + showTitle, + //! Set true to output some user information to stdout (e.g. user requested quit) + userInfoStdout, + //! If true, output mplot version to stdout + versionStdout, + //! If true (the default), then call swapBuffers() at the end of render() + renderSwapsBuffers, + /*! + * If true, rotation is about the scene origin, rather than the most central VisualModel. + * + * If false, the system finds the most central VisualModel, and rotates about the centroid + * of the bounding box that surrounds that VisualModel. + */ + rotateAboutSceneOrigin, + /*! + * If true, horizontal mouse movements rotate the scene about a chosen vertical axis, and + * vertical mouse movements rotate the vertical axis about the bottom of the user's + * viewport. This will be familiar to Blender users. Additionally, if the ctrl-modified + * mouse move mode is enabled, the scene is tilted about the axis coming out of the + * viewport. + * + * If false, horizontal mouse movements rotate the scene about the vertical axis of the + * user's viewport, vertcial mouse movements rotate the scene about the horizontal axis of + * the viewport, and ctrl-modified mouse movements rotate the scene about the axis coming + * out of the viewport. This was the original scene navigation scheme in mathplot and before + * that in morphologica. + */ + rotateAboutVertical, + /*! + * If true, write bounding boxes out to a json file /tmp/mathplot_bounding_boxes.json that + * can be read with the show_boundingboxes program + */ + boundingBoxesToJson, + //! If true, draw all the bounding boxes around the VisualModels + showBoundingBoxes, + /*! + * If true, then turn on the bounding box for the VM about which we are rotating and turn + * the others off (ignoring the value of 'showBoundingBoxes') + */ + highlightRotationVM, + /*! + * If true, the view of the scene follows a model translation (one of the VisualModels in + * the scene has to be nominated as the 'model to follow'. Useful for top-down views. The + * selected model to follow is in a member attribute followedModel + */ + viewFollowsVMTranslations, + /*! + * The view 'camera' rotates with the selected VM (followedModel) + */ + viewFollowsVMBehind, + }; + + //! Whether to render with perspective or orthographic + enum class perspective_type : uint32_t + { + perspective, + orthographic + }; + /*! * VisualOwnable - adds multi-context-safe GL calls to the 'scene' base class, VisualBase * @@ -68,7 +184,7 @@ export namespace mplot * \tparam glver The OpenGL version, encoded as a single int (see mplot::gl::version) */ template - class VisualOwnable : public mplot::VisualBase + class VisualOwnable { public: /*! @@ -76,7 +192,11 @@ export namespace mplot * such as a QWidget. We have to wait on calling init functions until an OpenGL * environment is guaranteed to exist. */ - VisualOwnable() { } + VisualOwnable() + { + this->sceneview.translate (this->scenetrans_default); + this->sceneview_tr.translate (this->scenetrans_default); + } /*! * Construct a new visualiser. The rule is 1 window to one Visual object. So, this creates a @@ -84,14 +204,21 @@ export namespace mplot */ VisualOwnable (const int _width, const int _height, const std::string& _title, const bool _version_stdout = true) { + this->sceneview.translate (this->scenetrans_default); + this->sceneview_tr.translate (this->scenetrans_default); this->window_w = _width; this->window_h = _height; this->title = _title; this->options.set (visual_options::versionStdout, _version_stdout); - this->init_gl(); } + // Hopefully, these will go + // A callback friendly wrapper for setContext + static void set_context (mplot::VisualOwnable* _v) { _v->setContext(); }; + // A callback friendly wrapper for releaseContext + static void release_context (mplot::VisualOwnable* _v) { _v->releaseContext(); }; + //! Deconstruct gl memory/context void deconstructCommon() { @@ -126,6 +253,15 @@ export namespace mplot } public: + // Public init that is given a context (window or widget) and then sets up the + // VisualResource, shaders and so on. + void init (mplot::win_t* ctx) + { + this->window = ctx; + this->init_resources(); + this->init_gl(); + } + // Do one-time init of the Visual's resources. This gets/creates the VisualResources, // registers this visual with resources, calls init_window for any glfw stuff that needs to // happen, and lastly initializes the freetype code. @@ -137,6 +273,107 @@ export namespace mplot this->visual_id = mplot::VisualResources::i().register_visual (this->glfn); } + // Hopefully this will go + /*! + * Set up the passed-in VisualModel (or indeed, VisualTextModel) with functions that need access to Visual attributes. + */ + template + void bindmodel (std::unique_ptr& model) + { + model->set_parent (this); + model->get_shaderprogs = &mplot::VisualBase::get_shaderprogs; + model->get_gprog = &mplot::VisualBase::get_gprog; + model->get_tprog = &mplot::VisualBase::get_tprog; + model->instanced_needs_update = &mplot::VisualBase::instanced_needs_update; + } + /*! + * Add a VisualModel to the scene as a unique_ptr. The Visual object takes ownership of the + * unique_ptr. The index into Visual::vm is returned. + */ + template + unsigned int addVisualModelId (std::unique_ptr& model) + { + std::unique_ptr> vmp = std::move(model); + if (vmp->instanced()) { this->state.set (visual_state::haveInstanced, true); } + this->vm.push_back (std::move(vmp)); + unsigned int rtn = (this->vm.size()-1); + return rtn; + } + + /*! + * Add a VisualModel to the scene as a unique_ptr. The Visual object takes ownership of the + * unique_ptr. A non-owning pointer to the model is returned. + */ + template + T* addVisualModel (std::unique_ptr& model) + { + std::unique_ptr> vmp = std::move(model); + if (vmp->instanced()) { this->state.set (visual_state::haveInstanced, true); } + this->vm.push_back (std::move(vmp)); + return static_cast(this->vm.back().get()); + } + + /*! + * Test the pointer vmp. Return vmp if it is owned by a unique_ptr in + * Visual::vm. If it is not present, return nullptr. + */ + const mplot::VisualModel* validVisualModel (const mplot::VisualModel* vmp) const + { + const mplot::VisualModel* rtn = nullptr; + for (unsigned int modelId = 0; modelId < this->vm.size(); ++modelId) { + if (this->vm[modelId].get() == vmp) { + rtn = vmp; + break; + } + } + return rtn; + } + + void setFollowedVM (const mplot::VisualModel* vm_to_follow) + { + for (unsigned int modelId = 0; modelId < this->vm.size(); ++modelId) { + if (this->vm[modelId].get() == vm_to_follow) { + this->followedVM = this->vm[modelId].get(); + this->followedLastViewMatrix = this->followedVM->getViewMatrix(); // COULD pass mat4 + break; + } + } + } + + /*! + * VisualModel Getter + * + * For the given \a modelId, return a (non-owning) pointer to the visual model. + * + * \return VisualModel pointer + */ + mplot::VisualModel* getVisualModel (unsigned int modelId) { return (this->vm[modelId].get()); } + + //! Remove the VisualModel with ID \a modelId from the scene. + void removeVisualModel (unsigned int modelId) { this->vm.erase (this->vm.begin() + modelId); } + + //! Remove the VisualModel whose pointer matches the VisualModel* vmp + void removeVisualModel (mplot::VisualModel* vmp) + { + unsigned int modelId = 0; + bool found_model = false; + for (modelId = 0; modelId < this->vm.size(); ++modelId) { + if (this->vm[modelId].get() == vmp) { + found_model = true; + break; + } + } + if (found_model == true) { this->vm.erase (this->vm.begin() + modelId); } + } + + void clear () { this->vm.clear(); } + + void set_cursorpos (double _x, double _y) { this->cursorpos = {static_cast(_x), static_cast(_y)}; } + + //! A callback function + static void callback_render (mplot::VisualBase* _v) { _v->render(); }; + + //! GLAD OpenGL function context pointer GladGLContext* glfn = nullptr; @@ -188,7 +425,7 @@ export namespace mplot } //! Render the scene - void render() noexcept final + void render() noexcept { this->setContext(); @@ -306,6 +543,23 @@ export namespace mplot } } + //! Compute a translation vector for text position, using Visual::text_z. + sm::vec textPosition (const sm::vec p0_coord) + { + // For the depth at which a text object lies, use this->text_z. Use forward + // projection to determine the correct z coordinate for the inverse + // projection. + sm::vec point = { 0.0f, 0.0f, this->text_z, 1.0f }; + sm::vec pp = this->projection * point; + float coord_z = pp[2]/pp[3]; // divide by pp[3] is divide by/normalise by 'w'. + // Construct the point for the location of the text + sm::vec p0 = { p0_coord.x(), p0_coord.y(), coord_z, 1.0f }; + // Inverse project the point + sm::vec v0; + v0.set_from (this->invproj * p0); + return v0; + } + //! Glad MX specific callback static GladGLContext* get_glfn (mplot::VisualBase* _v) { @@ -499,6 +753,1388 @@ export namespace mplot std::unique_ptr> textModel = nullptr; //! Text models for labels std::vector>> texts; + + public: + //! The OpenGL shader programs have an integer ID and are stored in a simple struct. There's + //! one for graphical objects and a text shader program, which uses textures to draw text on + //! quads. + mplot::visgl::visual_shaderprogs shaders; + //! Which shader is active for graphics shading. In practice, this is always 'projection2d' + mplot::visgl::graphics_shader_type active_gprog = mplot::visgl::graphics_shader_type::none; + //! Stores the info required to load the 2D projection shader + std::vector proj2d_shader_progs; + //! Stores the info required to load the text shader + std::vector text_shader_progs; + + // These static functions will be set as callbacks in each VisualModel object. + static mplot::visgl::visual_shaderprogs get_shaderprogs (mplot::VisualBase* _v) { return _v->shaders; }; + static GLuint get_gprog (mplot::VisualBase* _v) { return _v->shaders.gprog; }; + static GLuint get_tprog (mplot::VisualBase* _v) { return _v->shaders.tprog; }; + + static void instanced_needs_update (mplot::VisualBase* _v) { _v->instancedNeedsUpdate (true); } + + //! The colour of ambient and diffuse light sources + sm::vec light_colour = { 1.0f, 1.0f, 1.0f }; + //! Strength of the ambient light + float ambient_intensity = 1.0f; + //! Position of a diffuse light source + sm::vec diffuse_position = { 5.0f, 5.0f, 15.0f }; + //! Strength of the diffuse light source + float diffuse_intensity = 0.0f; + + //! Compute position and rotation of coordinate arrows in the bottom left of the screen + void positionCoordArrows() + { + // Find out the location of the bottom left of the screen and make the coord + // arrows stay put there. + + // Add the depth at which the object lies. Use forward projection to determine the + // correct z coordinate for the inverse projection. This assumes only one object. + sm::vec point = { 0.0f, 0.0f, this->sceneview[14], 1.0f }; // sceneview[14] is 'scenetrans.z' + sm::vec pp = this->projection * point; + float coord_z = pp[2]/pp[3]; // divide by pp[3] is divide by/normalise by 'w'. + + // Construct the point for the location of the coord arrows + sm::vec p0 = { this->coordArrowsOffset.x(), this->coordArrowsOffset.y(), coord_z, 1.0f }; + // Inverse project + sm::vec v0; + v0.set_from ((this->invproj * p0)); + // Translate the scene for the CoordArrows such that they sit in a single position on + // the screen + this->coordArrows->setSceneTranslation (v0); + // Apply rotation to the coordArrows model + sm::quaternion svrq = this->sceneview.rotation(); + svrq.renormalize(); + this->coordArrows->setViewRotation (svrq); + } + + // Update the coordinate axes labels + void updateCoordLabels (const std::string& x_lbl, const std::string& y_lbl, const std::string& z_lbl) + { + this->coordArrows->clear(); + this->coordArrows->x_label = x_lbl; + this->coordArrows->y_label = y_lbl; + this->coordArrows->z_label = z_lbl; + this->coordArrows->initAxisLabels(); + this->coordArrows->reinit(); + } + + // Update the lengths of the CoordArrows that (usually) appear in the corner of the screen + void updateCoordLengths (const sm::vec& _lengths, const float _thickness = 1.0f) + { + this->coordArrows->lengths = _lengths; + this->coordArrows->thickness = _thickness; + this->coordArrows->clear(); + this->coordArrows->initAxisLabels(); + this->coordArrows->reinit(); + } + + // state defaults. All state is false by default + constexpr sm::flags state_defaults() + { + sm::flags _state; + return _state; + } + + // State flags + sm::flags state = state_defaults(); + + // Options defaults. + constexpr sm::flags options_defaults() + { + sm::flags _options; + // Only with ImGui do we manually swap buffers, so this is true by default: + _options.set (visual_options::renderSwapsBuffers); + // For now, default to rotating about scene origin, as we ever did (Ctrl-k to change) + _options.set (visual_options::rotateAboutSceneOrigin); + // Also, for now, keep the Blender-like 'rotateAboutVertical' as a non-default option (Ctrl-d to change) + _options.set (visual_options::rotateAboutVertical, false); + + return _options; + } + + // Option flags + sm::flags options = options_defaults(); + + //! Returns true when the program has been flagged to end + bool readyToFinish() const { return this->state.test (visual_state::readyToFinish); } + + //! Returns true if we are in the paused state + bool paused() const { return this->state.test (visual_state::paused); } + + //! True if one of our added VisualModels is an instanced model + bool haveInstanced() const { return this->state.test (visual_state::haveInstanced); } + + //! Does our instanced data need to be pushed over to the GPU during render()? + bool instancedNeedsUpdate() const { return this->state.test (visual_state::instancedNeedsUpdate); } + void instancedNeedsUpdate (const bool val) { this->state.set (visual_state::instancedNeedsUpdate, val); } + + /* + * User-settable projection values for the near clipping distance, the far clipping distance + * and the field of view of the camera. + */ + + float zNear = 0.001f; + float zFar = 300.0f; + float fov = 30.0f; + + //! Time constants for the way the camera moves between a follow-me view and a + //! drone-view. One for translation, the other for rotation. + float trans_tc = 0.09f; + //! Rotational time constant + float rotn_tc = trans_tc; + + //! Which was is up in the scene? In OpenGL it's usually y, but may be changed to z in some cases + sm::vec scene_up = sm::vec::uy(); + //! Which way goes to the 'right' across the screen? Usually x + sm::vec scene_right = sm::vec::ux(); + //! Out of the screen? + sm::vec scene_out = sm::vec::uz(); + + //! Setter for visual_options::showCoordArrows + void showCoordArrows (const bool val) { this->options.set (visual_options::showCoordArrows, val); } + + //! If true, then place the coordinate arrows at the origin of the scene, rather than offset. + void coordArrowsInScene (const bool val) { this->options.set (visual_options::coordArrowsInScene, val); } + + //! Rotate about the nearest VisualModel? + void rotateAboutNearest (const bool val) + { this->options.set (mplot::visual_options::rotateAboutSceneOrigin, (val ? false : true)); } + + //! Rotate about a vertical axis in the scene? + void rotateAboutVertical (const bool val) { this->options.set (visual_options::rotateAboutVertical, val); } + + //! Set to true to show the title text within the scene + void showTitle (const bool val) { this->options.set (visual_options::showTitle, val); } + + //! Set true to output some user information to stdout (e.g. user requested quit) + void userInfoStdout (const bool val) { this->options.set (visual_options::userInfoStdout, val); } + + //! You can call this with val==false to manage exactly when you call the swapBuffer() method (for ImGui programs) + void renderSwapsBuffers (const bool val) { this->options.set (visual_options::renderSwapsBuffers, val); } + + //! How big should the steps in scene translation be when scrolling? + float scenetrans_stepsize = 0.02f; + + //! If you set this to true, then the mouse movements won't change scenetrans or rotation. + void sceneLocked (const bool val) { this->state.set (visual_state::sceneLocked, val); } + + //! Show bounding boxes? + void showBoundingBoxes (const bool val) { this->options.set (visual_options::showBoundingBoxes, val); } + + //! Highlight (with a bounding box) the VisualModel being used for rotation? + void highlightRotationVM (const bool val) { this->options.set (visual_options::highlightRotationVM, val); } + + //! Can change this to orthographic + perspective_type ptype = perspective_type::perspective; + + //! Orthographic screen left-bottom coordinate (you can change these to encapsulate your models) + sm::vec ortho_lb = { -1.3f, -1.0f }; + //! Orthographic screen right-top coordinate + sm::vec ortho_rt = { 1.3f, 1.0f }; + + //! The background colour; white by default. + std::array bgcolour = { 1.0f, 1.0f, 1.0f, 0.5f }; + + /* + * User can directly set bgcolour for any background colour they like, but + * here are convenience functions: + */ + + //! Set a white background colour for the Visual scene + void backgroundWhite() { this->bgcolour = { 1.0f, 1.0f, 1.0f, 0.5f }; } + //! Set a black background colour for the Visual scene + void backgroundBlack() { this->bgcolour = { 0.0f, 0.0f, 0.0f, 0.0f }; } + + //! Set sceneview and sceneview_tr back to scenetrans_default + void reset_sceneviews_to_scenetrans_default() + { + this->sceneview.set_identity(); + this->sceneview.translate (this->scenetrans_default); + this->sceneview_tr.set_identity(); + this->sceneview_tr.translate (this->scenetrans_default); + this->d_to_rotation_centre = -this->scenetrans_default[2]; + } + + //! Set the scene's x and y values at the same time. + void setSceneTransXY (const float _x, const float _y) + { + this->scenetrans_default[0] = _x; + this->scenetrans_default[1] = _y; + this->reset_sceneviews_to_scenetrans_default(); + } + //! Set the scene's y value. Use this to shift your scene objects left or right + void setSceneTransX (const float _x) + { + this->scenetrans_default[0] = _x; + this->reset_sceneviews_to_scenetrans_default(); + } + //! Set the scene's y value. Use this to shift your scene objects up and down + void setSceneTransY (const float _y) + { + this->scenetrans_default[1] = _y; + this->reset_sceneviews_to_scenetrans_default(); + } + //! Set the scene's z value. Use this to bring the 'camera' closer to your scene + //! objects (that is, your mplot::VisualModel objects). + void setSceneTransZ (const float _z) + { + if (_z > 0.0f) { + std::cerr << "WARNING setSceneTransZ(): Normally, the default z value is negative.\n"; + } + this->scenetrans_default[2] = _z; + this->reset_sceneviews_to_scenetrans_default(); + } + void setSceneTrans (float _x, float _y, float _z) + { + if (_z > 0.0f) { + std::cerr << "WARNING setSceneTrans(): Normally, the default z value is negative.\n"; + } + + this->scenetrans_default[0] = _x; + this->scenetrans_default[1] = _y; + this->scenetrans_default[2] = _z; + this->reset_sceneviews_to_scenetrans_default(); + } + void setSceneTrans (const sm::vec& _xyz) + { + if (_xyz[2] > 0.0f) { + std::cerr << "WARNING setSceneTrans(vec<>&): Normally, the default z value is negative.\n"; + } + this->scenetrans_default = _xyz; + this->reset_sceneviews_to_scenetrans_default(); + } + + void setSceneRotation (const sm::quaternion& _rotn) + { + this->rotation_default = _rotn; + this->sceneview.rotate (_rotn); + } + + // What is the scene view's current rotation quaternion? + sm::quaternion getSceneRotation() const { return this->sceneview.rotation(); } + // What is the scene view's current translation? + sm::vec getSceneTranslation() const { return this->sceneview.translation(); } + + void lightingEffects (const bool effects_on = true) + { + this->ambient_intensity = effects_on ? 0.4f : 1.0f; + this->diffuse_intensity = effects_on ? 0.6f : 0.0f; + } + + //! Save all the VisualModels in this Visual out to a GLTF format file + virtual void savegltf (const std::string& gltf_file) + { + std::ofstream fout; + fout.open (gltf_file, std::ios::out|std::ios::trunc); + if (!fout.is_open()) { throw std::runtime_error ("Visual::savegltf(): Failed to open file for writing"); } + fout << "{\n \"scenes\" : [ { \"nodes\" : [ "; + for (std::size_t vmi = 0u; vmi < this->vm.size(); ++vmi) { + fout << vmi << (vmi < this->vm.size()-1 ? ", " : ""); + } + fout << " ] } ],\n"; + + fout << " \"nodes\" : [\n"; + // for loop over VisualModels "mesh" : 0, etc + for (std::size_t vmi = 0u; vmi < this->vm.size(); ++vmi) { + fout << " { \"mesh\" : " << vmi + << ", \"translation\" : " << this->vm[vmi]->translation_str() + << (vmi < this->vm.size()-1 ? " },\n" : " }\n"); + } + fout << " ],\n"; + + fout << " \"meshes\" : [\n"; + // for each VisualModel: + for (std::size_t vmi = 0u; vmi < this->vm.size(); ++vmi) { + fout << " { "; + if (!this->vm[vmi]->name.empty()) { + fout << "\"name\" : \"" << this->vm[vmi]->name << "\", "; + } + fout << "\"primitives\" : [ { \"attributes\" : { \"POSITION\" : " << 1+vmi*4 + << ", \"COLOR_0\" : " << 2+vmi*4 + << ", \"NORMAL\" : " << 3+vmi*4 << " }, \"indices\" : " << vmi*4 << ", \"material\": 0 } ] }" + << (vmi < this->vm.size()-1 ? ",\n" : "\n"); + } + fout << " ],\n"; + + fout << " \"buffers\" : [\n"; + for (std::size_t vmi = 0u; vmi < this->vm.size(); ++vmi) { + // indices + fout << " {\"uri\" : \"data:application/octet-stream;base64," << this->vm[vmi]->indices_base64() << "\", " + << "\"byteLength\" : " << this->vm[vmi]->indices_bytes() << "},\n"; + // pos + fout << " {\"uri\" : \"data:application/octet-stream;base64," << this->vm[vmi]->vpos_base64() << "\", " + << "\"byteLength\" : " << this->vm[vmi]->vpos_bytes() << "},\n"; + // col + fout << " {\"uri\" : \"data:application/octet-stream;base64," << this->vm[vmi]->vcol_base64() << "\", " + << "\"byteLength\" : " << this->vm[vmi]->vcol_bytes() << "},\n"; + // norm + fout << " {\"uri\" : \"data:application/octet-stream;base64," << this->vm[vmi]->vnorm_base64() << "\", " + << "\"byteLength\" : " << this->vm[vmi]->vnorm_bytes() << "}"; + fout << (vmi < this->vm.size()-1 ? ",\n" : "\n"); + } + fout << " ],\n"; + + fout << " \"bufferViews\" : [\n"; + for (std::size_t vmi = 0u; vmi < this->vm.size(); ++vmi) { + // indices + fout << " { "; + fout << "\"buffer\" : " << vmi*4 << ", "; + fout << "\"byteOffset\" : 0, "; + fout << "\"byteLength\" : " << this->vm[vmi]->indices_bytes() << ", "; + fout << "\"target\" : 34963 "; + fout << " },\n"; + // vpos + fout << " { "; + fout << "\"buffer\" : " << 1+vmi*4 << ", "; + fout << "\"byteOffset\" : 0, "; + fout << "\"byteLength\" : " << this->vm[vmi]->vpos_bytes() << ", "; + fout << "\"target\" : 34962 "; + fout << " },\n"; + // vcol + fout << " { "; + fout << "\"buffer\" : " << 2+vmi*4 << ", "; + fout << "\"byteOffset\" : 0, "; + fout << "\"byteLength\" : " << this->vm[vmi]->vcol_bytes() << ", "; + fout << "\"target\" : 34962 "; + fout << " },\n"; + // vnorm + fout << " { "; + fout << "\"buffer\" : " << 3+vmi*4 << ", "; + fout << "\"byteOffset\" : 0, "; + fout << "\"byteLength\" : " << this->vm[vmi]->vnorm_bytes() << ", "; + fout << "\"target\" : 34962 "; + fout << " }"; + fout << (vmi < this->vm.size()-1 ? ",\n" : "\n"); + } + fout << " ],\n"; + + fout << " \"accessors\" : [\n"; + for (std::size_t vmi = 0u; vmi < this->vm.size(); ++vmi) { + this->vm[vmi]->computeVertexMaxMins(); + // indices + fout << " { "; + fout << "\"bufferView\" : " << vmi*4 << ", "; + fout << "\"byteOffset\" : 0, "; + // 5123 unsigned short, 5121 unsigned byte, 5125 unsigned int, 5126 float: + fout << "\"componentType\" : 5125, "; + fout << "\"type\" : \"SCALAR\", "; + fout << "\"count\" : " << this->vm[vmi]->indices_size(); + fout << "},\n"; + // vpos + fout << " { "; + fout << "\"bufferView\" : " << 1+vmi*4 << ", "; + fout << "\"byteOffset\" : 0, "; + fout << "\"componentType\" : 5126, "; + fout << "\"type\" : \"VEC3\", "; + fout << "\"count\" : " << this->vm[vmi]->vpos_size()/3; + // vertex position requires max/min to be specified in the gltf format + fout << ", \"max\" : " << this->vm[vmi]->vpos_max() << ", "; + fout << "\"min\" : " << this->vm[vmi]->vpos_min(); + fout << " },\n"; + // vcol + fout << " { "; + fout << "\"bufferView\" : " << 2+vmi*4 << ", "; + fout << "\"byteOffset\" : 0, "; + fout << "\"componentType\" : 5126, "; + fout << "\"type\" : \"VEC3\", "; + fout << "\"count\" : " << this->vm[vmi]->vcol_size()/3; + fout << "},\n"; + // vnorm + fout << " { "; + fout << "\"bufferView\" : " << 3+vmi*4 << ", "; + fout << "\"byteOffset\" : 0, "; + fout << "\"componentType\" : 5126, "; + fout << "\"type\" : \"VEC3\", "; + fout << "\"count\" : " << this->vm[vmi]->vnorm_size()/3; + fout << "}"; + fout << (vmi < this->vm.size()-1 ? ",\n" : "\n"); + } + fout << " ],\n"; + + // Default material is single sided, so make it double sided + fout << " \"materials\" : [ { \"doubleSided\" : true } ],\n"; + + fout << " \"asset\" : {\n" + << " \"generator\" : \"https://github.com/sebsjames/mathplot: mplot::Visual::savegltf() (ver " + << mplot::version_string() << ")\",\n" + << " \"version\" : \"2.0\"\n" // This version is the *glTF* version. + << " }\n"; + fout << "}\n"; + fout.close(); + } + + void set_winsize (int _w, int _h) { this->window_w = _w; this->window_h = _h; } + + // Accessing std::vector>> vm; from external code + std::vector>>::const_iterator next_vm_accessor; + void init_vm_accessor() { this->next_vm_accessor = this->vm.begin(); } + mplot::VisualModel* get_next_vm_accessor() + { + mplot::VisualModel* cvm = nullptr; + if (this->next_vm_accessor != this->vm.end()) { + cvm = (*this->next_vm_accessor).get(); + this->next_vm_accessor++; + } + return cvm; + } + + protected: + + //! Set up a perspective projection based on window width and height. Not public. + void setPerspective() + { + // Calculate aspect ratio + float aspect = static_cast(this->window_w) / static_cast(this->window_h ? this->window_h : 1); + // Set perspective projection + this->projection = sm::mat::perspective (this->fov, aspect, this->zNear, this->zFar); + // Compute the inverse projection matrix + this->invproj = this->projection.inverse(); + } + + /*! + * Set an orthographic projection. This is not a public function. To choose orthographic + * projection for your Visual, write something like: + * + * \code + * mplot::Visual<> v(width, height, title); + * v.ptype = mplot::perspective_type::orthographic; + * \endcode + */ + void setOrthographic() + { + this->projection = sm::mat::orthographic (this->ortho_lb, this->ortho_rt, this->zNear, this->zFar); + this->invproj = this->projection.inverse(); + } + + // Rotate about the point this->rotation_centre. Subroutine for computeSceneview. + void computeSceneview_about_rotation_centre() + { + sm::mat sv_tr; + sm::mat sv_rot; + sv_tr.translate (this->scenetrans_delta); + // A rotation delta in world frame about the 'screen centre' + sv_rot.translate (this->rotation_centre); + sv_rot.rotate (this->rotation_delta); + sv_rot.translate (-this->rotation_centre); + + this->sceneview = sv_tr * sv_rot * this->savedSceneview; + this->sceneview_tr = sv_tr * this->savedSceneview_tr; + } + + // Get a camera movement that moves us nearer to target. + template + sm::vec get_cam_movement (sm::mat& current, const sm::mat& target, + sm::vec& vel, const T tc) const + { + const sm::vec delta = target.translation() - current.translation(); + const sm::vec force = delta - (vel * T{2}); + sm::vec pos_shift = vel * tc; + vel += force * tc; + return pos_shift; + } + + template + sm::quaternion get_cam_rotation (const sm::quaternion& r_cur0, const sm::mat& target, + T& rvel, const T tc) const + { + sm::mat target0 = target; + target0.translate (-target.translation()); + sm::quaternion r_targ0 = target0.rotation(); + r_targ0.renormalize(); + + sm::quaternion r_sz = r_targ0 * r_cur0.inverse(); + sm::vec aa = r_sz.axis_angle(); + T delta = aa[3]; // The angle subtended by the rotation + T force = delta - (rvel * T{2}); + // rvel is radpersec delta/tc + T prop = rvel * tc; + rvel += force * tc; + sm::quaternion newpos = r_cur0.slerp (r_targ0, prop); + return newpos; // rather than prop, as in get_cam_movement + } + + // Compile-time function to create a rotate-about-y transform + static constexpr sm::mat rotate_about_y() + { + sm::mat r; + r.rotate (sm::vec<>::uy(), sm::mathconst::pi); + return r; + } + + // Hold an offset translation and rotation for the follow-me camera + static constexpr sm::vec folcam_offset_tr_default = {0, 0.01f, -0.06f}; + sm::vec folcam_offset_tr = folcam_offset_tr_default; + sm::quaternion folcam_offset_rot; + + sm::mat update_folcam_viewmatrix() + { + sm::mat fol_cur; + + if (this->followedVM == nullptr) { return fol_cur; } + + // Target view from the followedVM + //sm::mat fol_targ = this->followedVM->getViewMatrix() * this->folcam_offset; + sm::mat rmat; + rmat.rotate (folcam_offset_rot); + sm::mat fol_targ = this->followedVM->getViewMatrix() * rmat; + fol_targ.translate (folcam_offset_tr); + + // Compute folcam_viewmatrix from sceneview (it's the inverse, along with a rotation) + constexpr sm::mat rotn_y = rotate_about_y(); + sm::mat folcam_viewmatrix = this->sceneview.inverse() * rotn_y; + + const sm::vec folcam_vm_trans = folcam_viewmatrix.translation(); + + fol_cur.translate (folcam_vm_trans); // encode just the location of the following camera + + // The current rotation of the scene view + folcam_viewmatrix.translate (-folcam_vm_trans); + sm::quaternion r_cur0 = folcam_viewmatrix.rotation(); + r_cur0.renormalize(); + + // get_cam_movement computes the positional shift + sm::vec pos_shift = this->get_cam_movement (fol_cur, fol_targ, + this->followedVM_vel, this->trans_tc); + // get_cam_rotation computes the rotation for the next camera position + sm::quaternion cam_rotn = this->get_cam_rotation (r_cur0, fol_targ, + this->followedVM_rvel, this->rotn_tc); + + // set the translation/rotation into fol_cur + fol_cur.pretranslate (pos_shift); + fol_cur.rotate (cam_rotn); + + // Distance to rotation centre should be the distance to the followedVM + this->d_to_rotation_centre = folcam_offset_tr.length(); + + // fol_cur now contains the new position and orientation for the following camera + return fol_cur; + } + + // A follow-me camera view + void computeSceneview_for_follower() + { + sm::mat folcam_viewmatrix = this->update_folcam_viewmatrix(); + constexpr sm::mat rotn_y = rotate_about_y(); + this->sceneview = rotn_y * folcam_viewmatrix.inverse(); + this->savedSceneview = this->sceneview; + } + + // This is called every time render() is called + void computeSceneview() + { + if (this->options.test (visual_options::viewFollowsVMBehind) && this->followedVM != nullptr) { + // Use scenetrans_delta to shift the view with the scrollwheel + this->folcam_offset_tr += this->scenetrans_delta; + this->scenetrans_delta.zero(); + if (this->state.test (visual_state::scrolling)) { this->state.reset (visual_state::scrolling); } + this->computeSceneview_for_follower(); + return; + } + + if (std::abs(this->scenetrans_delta.sum()) > 0.0f || this->rotation_delta.is_zero_rotation() == false) { + // Calculate model view transformation - transforming from "model space" to "worldspace". + //std::cout << "standard view, call computeSceneview_about_rotation_centre\n"; + this->computeSceneview_about_rotation_centre(); + } // else don't change sceneview + //else { std::cout << "No changing sceneview...\n"; } + + //std::cout << "sceneview\n" << sceneview << std::endl; + + if (this->state.test (visual_state::scrolling)) { + this->scenetrans_delta.zero(); + this->state.reset (visual_state::scrolling); + } + + if (this->options.test (visual_options::viewFollowsVMTranslations) + && this->followedVM != nullptr + && this->followedLastViewMatrix != this->followedVM->getViewMatrix()) { // NEED KNOWLEDGE OF VISUALMODEL + + // Move camera the difference between followedLastViewMatrix and + // followedVM->getViewMatrix() in the screen frame of reference. + sm::vec fol_screenframe = (this->sceneview * followedLastViewMatrix.translation() + - this->sceneview * followedVM->getViewMatrix().translation()).less_one_dim(); + + this->sceneview.pretranslate (fol_screenframe); + this->sceneview_tr.pretranslate (fol_screenframe); + this->savedSceneview.pretranslate (fol_screenframe); + this->savedSceneview_tr.pretranslate (fol_screenframe); + + this->followedLastViewMatrix = this->followedVM->getViewMatrix(); // NEED KNOWLEDGE OF VISUALMODEL + } + } + + //! A vector of pointers to all the mplot::VisualModels (HexGridVisual, + //! ScatterVisual, etc) which are going to be rendered in the scene. + std::vector>> vm; + + //! If the view should follow a model (options viewFollowsVMTranslations and ...Rotations), this is the one. + mplot::VisualModel* followedVM = nullptr; + + //! Holds the current velocy of the followedVM follower + sm::vec followedVM_vel = {}; + //! Current rotational speed (how fast we slerp) + float followedVM_rvel = 0.0f; + + //! Holds the viewmatrix of the followedVM the last time we called render + sm::mat followedLastViewMatrix; + + // Read-from-json code that is called from init_gl in all implementations: + void read_scenetrans_from_json() + { + // If possible, read in scenetrans and rotation state from a special config file + try { + nlohmann::json vconf; + std::ifstream fi; + fi.open ("/tmp/Visual.json", std::ios::in); + fi >> vconf; + this->scenetrans_default[0] = vconf.contains("scenetrans_x") ? vconf["scenetrans_x"].get() : this->scenetrans_default[0]; + this->scenetrans_default[1] = vconf.contains("scenetrans_y") ? vconf["scenetrans_y"].get() : this->scenetrans_default[1]; + this->scenetrans_default[2] = vconf.contains("scenetrans_z") ? vconf["scenetrans_z"].get() : this->scenetrans_default[2]; + + this->rotation_default.w = vconf.contains("scenerotn_w") ? vconf["scenerotn_w"].get() : this->rotation_default.w; + this->rotation_default.x = vconf.contains("scenerotn_x") ? vconf["scenerotn_x"].get() : this->rotation_default.x; + this->rotation_default.y = vconf.contains("scenerotn_y") ? vconf["scenerotn_y"].get() : this->rotation_default.y; + this->rotation_default.z = vconf.contains("scenerotn_z") ? vconf["scenerotn_z"].get() : this->rotation_default.z; + + this->sceneview.set_identity(); + this->sceneview.translate (this->scenetrans_default); + this->sceneview.rotate (this->rotation_default); + this->sceneview_tr.set_identity(); + this->sceneview_tr.translate (this->scenetrans_default); + this->scenetrans_delta.zero(); + this->rotation_delta.reset(); + + } catch (...) { + // No problem if we couldn't read /tmp/Visual.json + } + } + + //! The window (and OpenGL context) for this Visual + mplot::win_t* window = nullptr; + + //! Each window has an ID number, which is passed to the owned VisualModels + uint32_t visual_id = std::numeric_limits::max(); + + //! Current window width + int window_w = 640; + //! Current window height + int window_h = 480; + + //! The title for the Visual. Used in window title and if saving out 3D model or png image. + std::string title = "mathplot"; + + //! The user's 'selected visual model'. For model specific changes to alpha and possibly colour + unsigned int selectedVisualModel = 0u; + + //! A little model of the coordinate axes. + std::unique_ptr> coordArrows; + + //! Position coordinate arrows on screen. Configurable at mplot::Visual construction. + sm::vec coordArrowsOffset = { -0.8f, -0.8f }; + + /* + * Variables to manage projection and rotation of the scene + */ + + //! Current cursor position + sm::vec cursorpos = {}; + + //! The default z position for VisualModels should be 'away from the screen' (negative) so we can see them! + constexpr static float zDefault = -5.0f; + + //! A delta scene translations + sm::vec scenetrans_delta = {}; + + //! Default for scene translation. This is a scene position that can be reverted to, to + //! 'reset the view'. This is copied into sceneview when user presses Ctrl-a. + sm::vec scenetrans_default = { 0.0f, 0.0f, zDefault }; + + //! The world depth at which text objects should be rendered + float text_z = -1.0f; + + //! Screen coordinates of the position of the last mouse press + sm::vec mousePressPosition = {}; + + //! Add additional rotation to the scene + sm::quaternion rotation_delta; + + //! The default rotation of the scene, to reconstruct the default sceneview matrix/reset rotation. + sm::quaternion rotation_default; + + //! A coordinate in the scene about which to perform a mouse-driven rotation. May be set to + //! the centre of the closest VisualModel object. + sm::vec rotation_centre = {}; + + // Distance to the 'rotation centre'. Used to scale the effect of the scroll wheel + float d_to_rotation_centre = -zDefault; + + //! The projection matrix is a member of this class. Value is set during setPerspective() or setOrthographic() + sm::mat projection; + + //! The inverse of the projection. Value is set during setPerspective() or setOrthographic() + sm::mat invproj; + + //! The sceneview matrix, which changes as the user moves the view with mouse + //! movements. Initialized in VisualOwnable constructor. + sm::mat sceneview; + + //! The non-rotating sceneview matrix, updated only from mouse translations (avoiding rotations) + sm::mat sceneview_tr; + + //! Saved sceneview at mouse button down + sm::mat savedSceneview; + + //! Saved sceneview_tr + sm::mat savedSceneview_tr; + + public: + + //! Getter for d_to_rotation_centre + float get_d_to_rotation_centre() const { return this->d_to_rotation_centre; } + + /* + * Generic callback handlers + */ + + using keyaction = mplot::keyaction; + using keymod = mplot::keymod; + using key = mplot::key; + // The key_callback handler uses GLFW codes, but they're in a mplot header (keys.h) + template + bool key_callback (int _key, int scancode, int action, int mods) // can't be virtual. + { + bool needs_render = false; + + if constexpr (owned == true) { // If Visual is 'owned' then the owning system deals with program exit + // Exit action + if (_key == key::q && (mods & keymod::control) && action == keyaction::press) { + this->signal_to_quit(); + } + } + + if (this->state.test (visual_state::sceneLocked) == false + && _key == key::c && (mods & keymod::control) && action == keyaction::press) { + this->options.flip (visual_options::showCoordArrows); + needs_render = true; + } + + if (_key == key::h && (mods & keymod::control) && action == keyaction::press) { + // Help to stdout: + std::cout << "Ctrl-h: Output this help to stdout\n" + << "Mouse-primary: rotate mode (use Ctrl to change axis)\n" + << "Mouse-secondary: translate mode\n"; + if constexpr (owned == true) { // If Visual is 'owned' then the owning system deals with program exit + std::cout << "Ctrl-q: Request exit\n"; + } + std::cout << "Ctrl-v: Un-pause\n" + << "Ctrl-l: Toggle the scene lock\n" + << "Ctrl-c: Toggle coordinate arrows\n" + << "Ctrl-s: Take a snapshot\n" + << "Ctrl-m: Save 3D models in .gltf format (open in e.g. blender)\n" + << "Ctrl-a: Reset default view\n" + << "Ctrl-o: Reduce field of view\n" + << "Ctrl-p: Increase field of view\n" + << "Ctrl-y: Cycle perspective\n" + << "Ctrl-k: Toggle rotate about central model or scene origin\n" + << "Ctrl-b: Toggle between 'rotate about vertical', or 'mathplot tilt'\n" + << "Ctrl-d: Switch the vertical axis used in 'rotate about vertical' mode\n" + << "Ctrl-z: Show the current scenetrans/rotation and save to /tmp/Visual.json\n" + << "Ctrl-u: Reduce zNear cutoff plane\n" + << "Ctrl-i: Increase zNear cutoff plane\n" + << "Ctrl-j: Toggle bounding boxes\n" + << "Ctrl-Shift-s: Output shaders to stdout\n" + << "F1-F10: Select model index (with shift: toggle hide)\n" + << "Shift-Left: Decrease opacity of selected model\n" + << "Shift-Right: Increase opacity of selected model\n" + << std::flush; + } + + if (_key == key::l && (mods & keymod::control) && action == keyaction::press) { + this->state.flip (visual_state::sceneLocked); + std::cout << "Scene is now " << (this->state.test (visual_state::sceneLocked) ? "" : "un-") << "locked\n"; + } + + if (_key == key::v && (mods & keymod::control) && action == keyaction::press) { + if (this->state.test (visual_state::paused)) { + this->state.set (visual_state::paused, false); + std::cout << "Scene un-paused\n"; + } // else no-op + } + + if (_key == key::s && (mods & (keymod::control | keymod::shift)) && action == keyaction::press) { + + if ((mods & (keymod::control | keymod::shift)) == (keymod::control | keymod::shift)) { + // Ctrl-Shift-s gives you the default shaders + std::cout << "The built-in shader programs are:\n"; + std::cout << "\nVisual.vert.glsl\n" + << "----------------\n" + << mplot::getDefaultVtxShader(glver) << std::endl; + std::cout << "\nVisual.frag.glsl\n" + << "----------------\n" + << mplot::getDefaultFragShader(glver) << std::endl; + std::cout << "\nVisText.vert.glsl\n" + << "----------------\n" + << mplot::getDefaultTextVtxShader(glver) << std::endl; + std::cout << "\nVisText.frag.glsl\n" + << "----------------\n" + << mplot::getDefaultTextFragShader(glver) << std::endl; + } else if (mods & keymod::control) { + // Ctrl-s saves a PNG + std::string fname (this->title); + mplot::tools::stripFileSuffix (fname); + fname += ".png"; + // Make fname 'filename safe' + mplot::tools::conditionAsFilename (fname); + this->saveImage (fname); + std::cout << "Saved image to '" << fname << "'\n"; + } + } + + // Save gltf 3D file + if (_key == key::m && (mods & keymod::control) && action == keyaction::press) { + std::string gltffile = this->title; + mplot::tools::stripFileSuffix (gltffile); + gltffile += ".gltf"; + mplot::tools::conditionAsFilename (gltffile); + this->savegltf (gltffile); + std::cout << "Saved 3D file '" << gltffile << "'\n"; + } + + if (_key == key::z && (mods & keymod::control) && action == keyaction::press) { + sm::quaternion rotn = this->sceneview.rotation(); + rotn.renormalize(); + sm::vec scenetrans = this->sceneview.translation(); + std::cout << "Scenetrans setup code:\n v.setSceneTrans (sm::vec{ float{" + << scenetrans.x() << "}, float{" + << scenetrans.y() << "}, float{" + << scenetrans.z() + << "} });" + << "\n v.setSceneRotation (sm::quaternion{ float{" + << rotn.w << "}, float{" << rotn.x << "}, float{" + << rotn.y << "}, float{" << rotn.z << "} });\n"; + std::cout << "Writing scene trans/rotation into /tmp/Visual.json... "; + std::ofstream fout; + fout.open ("/tmp/Visual.json", std::ios::out|std::ios::trunc); + if (fout.is_open()) { + fout << "{\"scenetrans_x\":" << scenetrans.x() + << ", \"scenetrans_y\":" << scenetrans.y() + << ", \"scenetrans_z\":" << scenetrans.z() + << ",\n \"scenerotn_w\":" << rotn.w + << ", \"scenerotn_x\":" << rotn.x + << ", \"scenerotn_y\":" << rotn.y + << ", \"scenerotn_z\":" << rotn.z << "}\n"; + fout.close(); + std::cout << "Success.\n"; + } else { + std::cout << "Failed.\n"; + } + } + + // Set selected model + if (_key == key::f1 && action == keyaction::press) { + this->selectedVisualModel = 0; + std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; + } else if (_key == key::f2 && action == keyaction::press) { + if (this->vm.size() > 1) { this->selectedVisualModel = 1; } + std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; + } else if (_key == key::f3 && action == keyaction::press) { + if (this->vm.size() > 2) { this->selectedVisualModel = 2; } + std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; + } else if (_key == key::f4 && action == keyaction::press) { + if (this->vm.size() > 3) { this->selectedVisualModel = 3; } + std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; + } else if (_key == key::f5 && action == keyaction::press) { + if (this->vm.size() > 4) { this->selectedVisualModel = 4; } + std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; + } else if (_key == key::f6 && action == keyaction::press) { + if (this->vm.size() > 5) { this->selectedVisualModel = 5; } + std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; + } else if (_key == key::f7 && action == keyaction::press) { + if (this->vm.size() > 6) { this->selectedVisualModel = 6; } + std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; + } else if (_key == key::f8 && action == keyaction::press) { + if (this->vm.size() > 7) { this->selectedVisualModel = 7; } + std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; + } else if (_key == key::f9 && action == keyaction::press) { + if (this->vm.size() > 8) { this->selectedVisualModel = 8; } + std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; + } else if (_key == key::f10 && action == keyaction::press) { + if (this->vm.size() > 9) { this->selectedVisualModel = 9; } + std::cout << "Selected visual model index " << this->selectedVisualModel << std::endl; + } + + // Toggle hide model if the shift key is down + if ((_key == key::f10 || _key == key::f1 || _key == key::f2 || _key == key::f3 + || _key == key::f4 || _key == key::f5 || _key == key::f6 + || _key == key::f7 || _key == key::f8 || _key == key::f9) + && action == keyaction::press && (mods & keymod::shift)) { + this->vm[this->selectedVisualModel]->toggleHide(); + } + + // Increment/decrement alpha for selected model + if (_key == key::left && (action == keyaction::press || action == keyaction::repeat) && (mods & keymod::shift)) { + if (!this->vm.empty()) { this->vm[this->selectedVisualModel]->decAlpha(); } + } + if (_key == key::right && (action == keyaction::press || action == keyaction::repeat) && (mods & keymod::shift)) { + if (!this->vm.empty()) { this->vm[this->selectedVisualModel]->incAlpha(); } + } + + // Reset view to default + if (this->state.test (visual_state::sceneLocked) == false + && _key == key::a && (mods & keymod::control) && action == keyaction::press) { + std::cout << "Reset to default view\n"; + this->sceneview.set_identity(); + this->sceneview_tr.set_identity(); + this->sceneview.translate (this->scenetrans_default); + this->sceneview.rotate (this->rotation_default); + this->sceneview_tr.translate (this->scenetrans_default); + this->scenetrans_delta.zero(); + this->rotation_delta.reset(); + this->d_to_rotation_centre = -this->scenetrans_default[2]; + //this->folcam_offset = folcam_default(); + this->folcam_offset_tr = folcam_offset_tr_default; + this->folcam_offset_rot.reset(); + needs_render = true; + } + + if (_key == key::k && (action == keyaction::press || action == keyaction::repeat) && (mods & keymod::control)) { + this->options.flip (visual_options::rotateAboutSceneOrigin); + std::cout << "Rotating about " + << (this->options.test (visual_options::rotateAboutSceneOrigin) ? "scene origin" : "central model") + << std::endl; + } + + if (_key == key::j && (action == keyaction::press || action == keyaction::repeat) && (mods & keymod::control)) { + this->options.flip (visual_options::showBoundingBoxes); + // Update all the VisualModels now: + auto vmi = this->vm.begin(); + while (vmi != this->vm.end()) { + (*vmi)->show_bb (this->options.test (visual_options::showBoundingBoxes)); + ++vmi; + } + } + + if (this->state.test (visual_state::sceneLocked) == false + && _key == key::o && (mods & keymod::control) && action == keyaction::press) { + this->fov -= 2; + if (this->fov < 1.0) { this->fov = 2.0; } + std::cout << "FOV reduced to " << this->fov << std::endl; + } + if (this->state.test (visual_state::sceneLocked) == false + && _key == key::p && (mods & keymod::control) && action == keyaction::press) { + this->fov += 2; + if (this->fov > 179.0) { this->fov = 178.0; } + std::cout << "FOV increased to " << this->fov << std::endl; + } + if (this->state.test (visual_state::sceneLocked) == false + && _key == key::u && (mods & keymod::control) && action == keyaction::press) { + this->zNear /= 2; + std::cout << "zNear reduced to " << this->zNear << std::endl; + } + if (this->state.test (visual_state::sceneLocked) == false + && _key == key::i && (mods & keymod::control) && action == keyaction::press) { + this->zNear *= 2; + std::cout << "zNear increased to " << this->zNear << std::endl; + } + if (this->state.test (visual_state::sceneLocked) == false + && _key == key::left_bracket && (mods & keymod::control) && action == keyaction::press) { + this->zFar /= 2; + std::cout << "zFar reduced to " << this->zFar << std::endl; + } + if (this->state.test (visual_state::sceneLocked) == false + && _key == key::right_bracket && (mods & keymod::control) && action == keyaction::press) { + this->zFar *= 2; + std::cout << "zFar increased to " << this->zFar << std::endl; + } + + if (_key == key::y && (mods & keymod::control) && action == keyaction::press) { + if (this->ptype == mplot::perspective_type::perspective) { + this->ptype = mplot::perspective_type::orthographic; + } else if (this->ptype == mplot::perspective_type::orthographic) { + this->ptype = mplot::perspective_type::perspective; + } + needs_render = true; + } + + if (_key == key::d && (mods & keymod::control) && action == keyaction::press) { + this->switch_scene_vertical_axis(); + } + + if (_key == key::b && (mods & keymod::control) && action == keyaction::press) { + this->options.flip (visual_options::rotateAboutVertical); + if (this->options.test (visual_options::rotateAboutVertical)) { + std::cout << "Mouse rotates scene about vertical axis\n"; + } else { + std::cout << "Mouse tilts scene as in the original mathplot\n"; + } + } + + this->key_callback_extra (_key, scancode, action, mods); + + return needs_render; + } + + // Switch between 'z' up and 'y' up + void switch_scene_vertical_axis() + { + if (this->scene_up == sm::vec<>::uy()) { + std::cout << "Changing 'scene up' to uz\n"; + this->scene_up = sm::vec<>::uz(); + this->scene_right = sm::vec<>::ux(); + this->scene_out = -sm::vec<>::uy(); + } else if (this->scene_up == sm::vec<>::uz()) { + std::cout << "Changing 'scene up' to uy\n"; + this->scene_up = sm::vec<>::uy(); + this->scene_right = sm::vec<>::ux(); + this->scene_out = sm::vec<>::uz(); + } else { + std::cout << "Not changing user-specified 'scene up' from " << this->scene_up << "\n"; + } + } + + //! Rotate the scene about axis by angle (angle in radians) + void rotate_scene (const sm::vec& axis, const float angle) + { + sm::quaternion rotnQuat (axis, -angle); + this->sceneview.rotate (rotnQuat); + } + + //! Find the rotation centre; either the scene origin or the centre of a perceptually nearby VM + void find_rotation_centre() + { + // When rotating about scene origin, find translation of scene centre from screen centre + if (this->options.test (visual_options::rotateAboutSceneOrigin) == true) { + this->rotation_centre = this->savedSceneview.translation(); + return; + } + + // Otherwise, find the centre of a visual model to rotate about + constexpr sm::vec v1 = { 0.0f, 0.0f, -100.0f }; + constexpr sm::vec v2 = { 0.0f, 0.0f, 100.0f }; + constexpr sm::vec v2v1 = v1 - v2; + + // A rotation delta in world frame about the 'screen centre'. This is a default: + if (this->rotation_centre == sm::vec{}) { + this->rotation_centre = { 0.0f, 0.0f, this->savedSceneview.translation().z() + this->scenetrans_delta.z() }; + } + + // There's an option to write out the bounding box corners to a file that can be + // displayed with debug_boundingboxes.cpp + std::ofstream fout; + uint32_t ci = 0; + if (options.test (visual_options::boundingBoxesToJson)) { + fout.open ("/tmp/mathplot_bounding_boxes.json", std::ios::out | std::ios::trunc); + if (fout.is_open()) { fout << "{\n"; } + } + + std::multimap, mplot::VisualModel*> > possible_centres; + auto vmi = this->vm.begin(); + while (vmi != this->vm.end()) { + + // vm_bools comes from VisualModel and would need to be shared + if ((*vmi)->flags.test (mplot::vm_bools::compute_bb) && !(*vmi)->flags.test (mplot::vm_bools::twodimensional)) { + + sm::vec tr_bb_centre = (this->savedSceneview * (*vmi)->get_viewmatrix_bb_centre()).less_one_dim(); + + if (options.test (visual_options::boundingBoxesToJson) && fout.is_open()) { + sm::range> modelbb = (*vmi)->bb; // Get the VisualModel bounding box + modelbb -= (*vmi)->bb.mid(); // centre the bounding box about (VM frame's) origin + modelbb += tr_bb_centre; + fout << " \"b" << (ci + 1) << "\": [" << modelbb.min.str_comma_separated() << "],\n"; + fout << " \"b" << (ci + 2) << "\": [" << modelbb.max.str_comma_separated() << "],\n"; + ci += 2; + } + + // Highlight central VM in any case. Really, want to highlight the selected possible centre. + if (options.test (visual_options::highlightRotationVM)) { (*vmi)->show_bb (false); } + + // Find perpendicular distance from line to point pc + sm::vec cv = tr_bb_centre - v1; + float pdist = cv.length() * std::sin (v2v1.angle (cv)); + + if (tr_bb_centre[2] < 0.0f) { // Only if in front of viewer (z must be negative) + // Perp. distance as key, value is tuple of BB centre and visualmodel pointer + possible_centres.insert ({ pdist, { tr_bb_centre, (*vmi).get() } }); + } + } + ++vmi; + } + + if (options.test (visual_options::boundingBoxesToJson) && fout.is_open()) { + fout << " \"n\": " << ci << "\n}\n"; + fout.close(); + } + + if (!possible_centres.empty()) { + const auto [rcentre, vmptr] = possible_centres.begin()->second; + this->rotation_centre = rcentre; + this->d_to_rotation_centre = this->rotation_centre.length(); + if (options.test (visual_options::highlightRotationVM)) { vmptr->show_bb (true); } + } // else don't change rotation_centre + } + + virtual bool cursor_position_callback (double x, double y) + { + this->cursorpos[0] = static_cast(x); + this->cursorpos[1] = static_cast(y); + + sm::vec mouseMoveWorld = { 0.0f, 0.0f, 0.0f }; + + bool needs_render = false; + + // Mouse-movement gain + constexpr float mm_gain = 160.0f; + + // This is "rotate the scene" (and not "rotate one VisualModel") + if (this->state.test (visual_state::rotateMode)) { + // Convert mousepress/cursor positions (in pixels) to the range -1 -> 1: + sm::vec p0_coord = this->mousePressPosition; + p0_coord -= this->window_w * 0.5f; + p0_coord /= this->window_w * 0.5f; + sm::vec p1_coord = this->cursorpos; + p1_coord -= this->window_w * 0.5f; + p1_coord /= this->window_w * 0.5f; + // Note: don't update this->mousePressPosition until user releases button. + + // Add the depth at which the object lies. Use forward projection to determine the + // correct z coordinate for the inverse projection. This assumes only one object. + sm::vec point = { 0.0f, 0.0f, this->savedSceneview.translation().z(), 1.0f }; + sm::vec pp = this->projection * point; + float coord_z = pp[2] / pp[3]; // divide by pp[3] is divide by/normalise by 'w'. + + // p0_coord/p1_coord in range -1 to 1, with a z value of 1. + sm::vec p0 = { p0_coord[0], p0_coord[1], coord_z, 1.0f }; + sm::vec p1 = { p1_coord[0], p1_coord[1], coord_z, 1.0f }; + + // Apply the inverse projection to get two points in the world frame of reference + // for the mouse movement + sm::vec v0 = this->invproj * p0; + sm::vec v1 = this->invproj * p1; + + /* + * This computes the difference between v0 and v1, the 2 mouse positions in the + * world space. Note the swap between x and y. mouseMoveWorld is used as the + * rotation axis in the viewer's frame of reference or its values are used to set + * rotations about scene axes (if rotateAboutVertical is true) + */ + if (this->state.test (visual_state::rotateModMode)) { + // Sort of "rotate the page" mode. + mouseMoveWorld[2] = (-(v1[1] - v0[1]) + (v1[0] - v0[0])); + } else { + mouseMoveWorld[1] = -(v1[0] - v0[0]); + mouseMoveWorld[0] = -(v1[1] - v0[1]); + } + mouseMoveWorld *= mm_gain; + + if (this->options.test (visual_options::rotateAboutVertical) == true + && this->options.test (visual_options::viewFollowsVMBehind) == false) { + + if (this->state.test (visual_state::rotateModMode)) { + // What to do about rotate mod mode in this rotation scheme? Rotate about the missing axis for now. + this->rotation_delta.set_rotation (this->scene_out, mouseMoveWorld[2] * -sm::mathconst::deg2rad); + } else { + // For now, rotate about the scene up axis + sm::vec<> mod_up = this->savedSceneview.rotation() * this->scene_up; + sm::quaternion r1 (mod_up, mouseMoveWorld[1] * -sm::mathconst::deg2rad); + sm::quaternion r2 (this->scene_right, mouseMoveWorld[0] * -sm::mathconst::deg2rad); + this->rotation_delta = r2 * r1; + } + } else if (this->options.test (visual_options::viewFollowsVMBehind) == true) { + //std::cout << "\nmouseMoveWorld[0]: " << mouseMoveWorld[0] << std::endl; // pitch + //std::cout << "mouseMoveWorld[1]: " << mouseMoveWorld[1] << std::endl; // about +- 40ish. leftright yaw + float pitch = mouseMoveWorld[0]; + float yaw = mouseMoveWorld[1]; + pitch = pitch > 10.0f ? 10.0f : pitch; + pitch = pitch < -65.0f ? -65.0f : pitch; // negative pitch is 'looking down' on the agent + yaw = yaw > 45.0f ? 45.0f : yaw; + yaw = yaw < -45.0f ? -45.0f : yaw; + + sm::quaternion r1 (this->scene_up, yaw * sm::mathconst::deg2rad); + sm::quaternion r2 (this->scene_right, pitch * -sm::mathconst::deg2rad); + this->folcam_offset_rot = r2 * r1; + + } else { + // rotation_delta is the mouse-commanded rotation in the scene frame of reference + this->rotation_delta.set_rotation (mouseMoveWorld, mouseMoveWorld.length() * -sm::mathconst::deg2rad); + } + + needs_render = true; + + } else if (this->state.test (visual_state::translateMode)) { // allow only rotate OR translate for a single mouse movement + // Convert mousepress/cursor positions (in pixels) to the range -1 -> 1: + sm::vec p0_coord = this->mousePressPosition; + p0_coord -= this->window_w * 0.5f; + p0_coord /= this->window_w * 0.5f; + sm::vec p1_coord = this->cursorpos; + p1_coord -= this->window_w * 0.5f; + p1_coord /= this->window_w * 0.5f; + + this->mousePressPosition = this->cursorpos; + + // Add the depth at which the object lies. Use forward projection to determine the + // correct z coordinate for the inverse projection. This assumes only one object. + sm::vec point = { 0.0f, 0.0f, -this->d_to_rotation_centre, 1.0f }; + sm::vec pp = this->projection * point; + float coord_z = pp[2] / pp[3]; // divide by pp[3] is divide by/normalise by 'w'. + + // Construct two points for the start and end of the mouse movement + sm::vec p0 = { p0_coord[0], p0_coord[1], coord_z, 1.0f }; + sm::vec p1 = { p1_coord[0], p1_coord[1], coord_z, 1.0f }; + // Apply the inverse projection to get two points in the world frame of reference: + sm::vec v0 = this->invproj * p0; + sm::vec v1 = this->invproj * p1; + // This computes the difference betwen v0 and v1, the 2 mouse positions in the world + mouseMoveWorld[0] = (v1[0] / v1[3]) - (v0[0] / v0[3]); + mouseMoveWorld[1] = (v1[1] / v1[3]) - (v0[1] / v0[3]); + // Note: mouseMoveWorld[2] is unmodified + + // We "translate the whole scene" - used by 2D projection shaders + this->scenetrans_delta[0] += mouseMoveWorld[0]; + + if (this->options.test (visual_options::viewFollowsVMBehind) == true) { + this->scenetrans_delta[1] += mouseMoveWorld[1]; // opp. sense in follow-me + } else { + this->scenetrans_delta[1] -= mouseMoveWorld[1]; + } + + needs_render = true; // updates viewproj; uses this->scenetrans + } + + return needs_render; + } + + virtual void mouse_button_callback (int button, int action, int mods = 0) + { + // If the scene is locked, then ignore the mouse movements + if (this->state.test (visual_state::sceneLocked)) { return; } + + // Record the position and rotation at which the button was pressed + if (action == keyaction::press) { // Button down + this->mousePressPosition = this->cursorpos; + this->savedSceneview = this->sceneview; + this->savedSceneview_tr = this->sceneview_tr; + this->scenetrans_delta.zero(); + this->rotation_delta.reset(); + } else if (action == keyaction::release) { + // On mouse button release, zero the deltas: + this->scenetrans_delta.zero(); + this->rotation_delta.reset(); + } + + this->find_rotation_centre(); + + if (button == mplot::mousebutton::left) { // Primary button means rotate + if (action == keyaction::press) { + this->state.set (visual_state::mouseButtonLeftPressed); + } else if (action == keyaction::release) { + this->state.set (visual_state::mouseButtonLeftPressed, false); + } + this->state.set (visual_state::rotateModMode, ((mods & keymod::control) ? true : false)); + this->state.set (visual_state::rotateMode, (action == keyaction::press)); + this->state.set (visual_state::translateMode, false); + } else if (button == mplot::mousebutton::right) { // Secondary button means translate + if (action == keyaction::press) { + this->state.set (visual_state::mouseButtonRightPressed); + } else if (action == keyaction::release) { + this->state.set (visual_state::mouseButtonRightPressed, false); + } + this->state.set (visual_state::rotateMode, false); + this->state.set (visual_state::translateMode, (action == keyaction::press)); + } + + this->mouse_button_callback_extra (button, action, mods); + } + + virtual bool window_size_callback (int width, int height) + { + this->window_w = width; + this->window_h = height; + return true; // needs_render + } + + virtual void window_close_callback() + { + if (this->options.test (visual_options::preventWindowCloseWithButton) == false) { + this->signal_to_quit(); + } else { + std::cerr << "Ignoring user request to exit (Visual::preventWindowCloseWithButton)\n"; + } + } + + //! When user scrolls, we translate the scene + virtual bool scroll_callback (double xoffset, double yoffset) + { + // yoffset non-zero indicates that the most common scroll wheel is changing. If there's + // a second scroll wheel, xoffset will be passed non-zero. They'll be 0 or +/- 1. + + if (this->state.test (visual_state::sceneLocked)) { return false; } + + this->savedSceneview = this->sceneview; + this->savedSceneview_tr = this->sceneview_tr; + this->scenetrans_delta.zero(); + this->rotation_delta.reset(); + this->state.set (visual_state::scrolling); + + if (this->ptype == perspective_type::orthographic) { + // In orthographic, the wheel should scale ortho_lb and ortho_rt + sm::vec _lb = this->ortho_lb + (yoffset * this->scenetrans_stepsize); + sm::vec _rt = this->ortho_rt - (yoffset * this->scenetrans_stepsize); + if (_lb < 0.0f && _rt > 0.0f) { + this->ortho_lb = _lb; + this->ortho_rt = _rt; + } + + } else { // perspective_type::perspective + + // xoffset does what mouse drag left/right in rotateModMode does (L/R scene trans) + this->scenetrans_delta[0] -= xoffset * this->scenetrans_stepsize; + + // yoffset does the 'in-out zooming' + + // How to make scenetrans_stepsize adaptive to the scale of the environment and change when close to objects? + float y_step = static_cast(yoffset) * this->scenetrans_stepsize * this->d_to_rotation_centre; + sm::vec scroll_move_y = { 0.0f, y_step, 0.0f, 1.0f }; + + this->scenetrans_delta[2] += scroll_move_y[1]; + + if (this->d_to_rotation_centre > (this->zFar / 2.0f) && scroll_move_y[1] < 0.0f) { + // Cancel movement + this->scenetrans_delta[2] = 0.0f; + scroll_move_y[1] = 0.0f; + } + + this->d_to_rotation_centre -= this->scenetrans_delta[2]; + } + return true; // needs_render + } + + //! Extra key callback handling, making it easy for client programs to implement their own actions + virtual void key_callback_extra ([[maybe_unused]] int key, [[maybe_unused]] int scancode, + [[maybe_unused]] int action, [[maybe_unused]] int mods) {} + + //! Extra mousebutton callback handling, making it easy for client programs to implement their own actions + virtual void mouse_button_callback_extra ([[maybe_unused]] int button, [[maybe_unused]] int action, + [[maybe_unused]] int mods) {} + + //! A callback that client code can set so that it knows when user has signalled to + //! mplot::Visual that it's quit time. + std::function external_quit_callback; + + protected: + //! This internal quit function sets a 'readyToFinish' flag that your code can respond to, + //! and calls an external callback function that you may have set up. + void signal_to_quit() + { + if (this->options.test (visual_options::userInfoStdout)) { std::cout << "User requested exit.\n"; } + // 1. Set our 'readyToFinish' flag to true + this->state.set (visual_state::readyToFinish); + // 2. Call any external callback that's been set by client code + if (this->external_quit_callback) { this->external_quit_callback(); } + } + + //! Unpause, allowing pauseOpen() to return + void unpause() { this->state.reset (visual_state::paused); } }; } // namespace mplot diff --git a/mplot/VisualResources.h b/mplot/VisualResources.h index e490085f..eaae0c52 100644 --- a/mplot/VisualResources.h +++ b/mplot/VisualResources.h @@ -9,13 +9,6 @@ */ module; -#include -#include -#include -#include -#include -#include - #if defined __gl3_h_ || defined __gl_h_ // GL headers have been externally included #else @@ -24,41 +17,54 @@ module; # include #endif -#include -#include -#include - // FreeType for text rendering #include #include FT_FREETYPE_H +#include +#include +#include +#include + +#include +#include +#include + export module mplot.core:visualresources; -import :visualface; -import :visualfont; -import :visualresourcesbase; -import :textfeatures; + +import mplot.visualfont; +import mplot.visualface; +import mplot.textfeatures; import sm.vec; export namespace mplot { - // Pointers to mplot::VisualBase are used to index font faces - //template - //class VisualBase; - - //! Singleton resource class for mplot::Visual scenes. + //! Singleton resource class for mplot::Visual scenes. (base class, with no GL calls, and no + //! instance function) template - class VisualResources : public VisualResourcesBase + class VisualResources { private: VisualResources(){} - ~VisualResources() { this->faces.clear(); } + ~VisualResources() + { + this->faces.clear(); + // As with the case for faces, when each mplot::Visual goes out of scope, the FreeType + // instance gets cleaned up. So at this stage freetypes should also be empy and nothing + // will happen here either. + for (auto& ft : this->freetypes) { FT_Done_FreeType (ft.second); } + } //! The collection of VisualFaces generated for this instance of the //! application. Create one VisualFace for each unique combination of VisualFont //! and fontpixels (the texture resolution) std::map*>, std::unique_ptr> faces; + + //! FreeType library object + std::map*, FT_Library> freetypes; + public: VisualResources(const VisualResources&) = delete; VisualResources& operator=(const VisualResources &) = delete; @@ -90,6 +96,20 @@ export namespace mplot } } + //! When a mplot::Visual goes out of scope, its freetype library instance should be + //! deinitialized. + void freetype_deinit (mplot::VisualBase* _vis) + { + // First clear the faces associated with VisualBase<>* _vis + this->clearVisualFaces (_vis); + // Second, clean up the FreeType library instance and erase from this->freetypes + auto freetype = this->freetypes.find (_vis); + if (freetype != this->freetypes.end()) { + FT_Done_FreeType (freetype->second); + this->freetypes.erase (freetype); + } + } + //! The instance public function. Uses the very short name 'i' to keep code tidy. //! This relies on C++11 magic statics (N2660). static auto& i() @@ -99,7 +119,7 @@ export namespace mplot } //! A function to call to simply make sure the singleton instance exists - void create() final {} + void create() {} //! Return a pointer to a VisualFace for the given \a font at the given texture //! resolution, \a fontpixels and the given window (i.e. OpenGL context) \a _win. @@ -211,12 +231,35 @@ export namespace mplot if (this->instparam_data.ready()) { this->instparam_data.copy_to_gpu(); } } + /*! + * SSBO management + */ + //! Instanced rendering mode (SSBO access). position data stored in SSBO index 1 (must match GLSL code) + static constexpr unsigned int instance_index = 1; + //! colour, scale, rotation stored in SSBO index 2 + static constexpr unsigned int instparam_index = 2; + //! one 3D vector is 3 floats + static constexpr unsigned int floats_per_instance = 3; + //! Instance params are: colour/alpha (4 floats), scale (1 float) + static constexpr unsigned int floats_per_instparam = 5; + + //! This will control how much GPU RAM is allocated when using instanced rendering + //! (Hopefully, when I'm finished, the RAM will be allocated only if at least one + //! VisualModel is marked 'instanced'). Makes a big difference to speed of operation (unless + //! I can send a portion of a buffer to the GPU). + static constexpr unsigned int max_instances = 32 * 1024; + static constexpr unsigned int max_instance_floats = floats_per_instance * max_instances; + static constexpr unsigned int max_instparam_floats = floats_per_instparam * max_instances; + //! Shader Storage Buffer Object for instanced rendering - this holds positions only - mplot::gl::ssbo::instance_index, - float, mplot::VisualResourcesBase::max_instance_floats> instance_data; + mplot::gl::ssbo::instance_index, + float, mplot::VisualResources::max_instance_floats> instance_data; //! Shader Storage Buffer Object for instanced rendering - this holds colour, alpha and scale - mplot::gl::ssbo::instparam_index, - float, mplot::VisualResourcesBase::max_instparam_floats> instparam_data; + mplot::gl::ssbo::instparam_index, + float, mplot::VisualResources::max_instparam_floats> instparam_data; + + // The Current location from which space in the instance SSBOs should be allocated + unsigned int instance_top = 0; }; } // namespace mplot diff --git a/mplot/VisualResourcesBase.h b/mplot/VisualResourcesBase.h deleted file mode 100644 index 697964e0..00000000 --- a/mplot/VisualResourcesBase.h +++ /dev/null @@ -1,100 +0,0 @@ -/*! - * \file - * - * Declares a VisualResource class to hold the information about Freetype and any other - * one-per-program resources. - * - * \author Seb James - * \date November 2020 - */ -module; - -#include -#include -#include -// FreeType for text rendering -#include -#include FT_FREETYPE_H - -export module mplot.core:visualresourcesbase; - -import :visualfont; - -export namespace mplot -{ - // Pointers to mplot::VisualBase are used to index font faces - template - class VisualBase; - - //! Singleton resource class for mplot::Visual scenes. (base class, with no GL calls, and no - //! instance function) - template - class VisualResourcesBase - { - protected: - VisualResourcesBase() { } - ~VisualResourcesBase() - { - // As with the case for faces, when each mplot::Visual goes out of scope, the FreeType - // instance gets cleaned up. So at this stage freetypes should also be empy and nothing - // will happen here either. - for (auto& ft : this->freetypes) { FT_Done_FreeType (ft.second); } - } - - //! FreeType library object - std::map*, FT_Library> freetypes; - - public: - VisualResourcesBase(const VisualResourcesBase&) = delete; - VisualResourcesBase& operator=(const VisualResourcesBase &) = delete; - VisualResourcesBase(VisualResourcesBase &&) = delete; - VisualResourcesBase & operator=(VisualResourcesBase &&) = delete; - - //! A function to call to simply make sure the singleton instance exists. In derived class - //! this could be a no-op. - virtual void create() = 0; - - // Note: freetype_init function is in derived class - - //! When a mplot::Visual goes out of scope, its freetype library instance should be - //! deinitialized. - void freetype_deinit (mplot::VisualBase* _vis) - { - // First clear the faces associated with VisualBase<>* _vis - this->clearVisualFaces (_vis); - // Second, clean up the FreeType library instance and erase from this->freetypes - auto freetype = this->freetypes.find (_vis); - if (freetype != this->freetypes.end()) { - FT_Done_FreeType (freetype->second); - this->freetypes.erase (freetype); - } - } - - // Note: get/clearVisualFace functions are in derived classes - virtual void clearVisualFaces (mplot::VisualBase* _vis) = 0; - - /*! - * SSBO management - */ - //! Instanced rendering mode (SSBO access). position data stored in SSBO index 1 (must match GLSL code) - static constexpr unsigned int instance_index = 1; - //! colour, scale, rotation stored in SSBO index 2 - static constexpr unsigned int instparam_index = 2; - //! one 3D vector is 3 floats - static constexpr unsigned int floats_per_instance = 3; - //! Instance params are: colour/alpha (4 floats), scale (1 float) - static constexpr unsigned int floats_per_instparam = 5; - - //! This will control how much GPU RAM is allocated when using instanced rendering - //! (Hopefully, when I'm finished, the RAM will be allocated only if at least one - //! VisualModel is marked 'instanced'). Makes a big difference to speed of operation (unless - //! I can send a portion of a buffer to the GPU). - static constexpr unsigned int max_instances = 32 * 1024; - static constexpr unsigned int max_instance_floats = floats_per_instance * max_instances; - static constexpr unsigned int max_instparam_floats = floats_per_instparam * max_instances; - - // The Current location from which space in the instance SSBOs should be allocated - unsigned int instance_top = 0; - }; - -} // namespace mplot diff --git a/mplot/VisualTextModel.h b/mplot/VisualTextModel.h index 74c44a8f..c7a472b6 100644 --- a/mplot/VisualTextModel.h +++ b/mplot/VisualTextModel.h @@ -5,62 +5,54 @@ * characters. This is for use in VisualModel-derived classes. Within the backend, the * VisualTextModel classes are used directly. * - * There is a hierarchy of implementation files and a base class underlying this, but in client - * code, you just use a VisualTextModel. - * - * This implementation class adds OpenGL function calls to the base class to make a finished - * VisualTextModel class. - * * \author Seb James * \date Oct 2020 - Mar 2026 */ module; -#include +#include +#include +#include +#include +#include +#include #include +#include -#if defined __gl3_h_ || defined __gl_h_ -// GL headers have been externally included -#else -// Include GLAD header -# define GLAD_GL_IMPLEMENTATION -# include -#endif +#include #include -#include #include +#include export module mplot.visualtextmodel; -import mplot.visualtextmodelbase; import mplot.visualcommon; - -// Need these here, they're from core, so will have to be extracted from core. -import :visualface; -import :visualresources; -import :textfeatures; -import :textgeometry; +import mplot.textgeometry; +import mplot.textfeatures; +import mplot.visualface; import sm.quaternion; +import sm.mat; import sm.vec; export namespace mplot { //! Forward declaration of a VisualBase class - //template class VisualBase; + template class VisualBase; /*! - * Implementation of a separate data-containing model which is used to render text. It is - * intended that this could comprise part of a mplot::Visual or a mplot::VisualModel. It has its - * own render call. Multicontext-safe GL version (GLAD). + * This is the base class for VisualTextModel containing common code, but no GL function calls. */ template - class VisualTextModel : public mplot::VisualTextModelBase + struct VisualTextModel { public: VisualTextModel (mplot::TextFeatures _tfeatures) - : VisualTextModelBase::VisualTextModelBase (_tfeatures) {} + { + this->tfeatures = _tfeatures; + this->fontscale = tfeatures.fontsize / static_cast(tfeatures.fontres); + } ~VisualTextModel() { @@ -71,7 +63,7 @@ export namespace mplot } //! Render the VisualTextModel - void render() final + void render() { if (this->hide == true) { return; } @@ -118,8 +110,13 @@ export namespace mplot mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); } +#if 0 + //! Get the GladGLContext function pointer + std::function*)> get_glfn; +#endif + //! Compute the geometry for a sample text. - mplot::TextGeometry getTextGeometry (const std::string& _txt) final + mplot::TextGeometry getTextGeometry (const std::string& _txt) { mplot::TextGeometry geom; @@ -143,7 +140,7 @@ export namespace mplot } //! Return the geometry for the stored txt - mplot::TextGeometry getTextGeometry() final + mplot::TextGeometry getTextGeometry() { mplot::TextGeometry geom; @@ -198,6 +195,8 @@ export namespace mplot //! With the given text and font size information, create the quads for the text. void setupText (const std::basic_string& _txt) { + constexpr bool debug_textquads = false; + if (this->face == nullptr) { this->face = VisualResources::i().getVisualFace (this->tfeatures, this->parentVis, this->get_glfn(this->parentVis)); @@ -242,7 +241,7 @@ export namespace mplot xpos+w, ypos+h, text_epsilon, xpos+w, ypos, text_epsilon }; text_epsilon -= 10.0f * std::numeric_limits::epsilon(); - if constexpr (mplot::VisualTextModelBase::debug_textquads == true) { + if constexpr (debug_textquads == true) { std::cout << "Text box added as quad from\n(" << tbox[0] << "," << tbox[1] << "," << tbox[2] << ") to (" << tbox[3] << "," << tbox[4] << "," << tbox[5] @@ -274,7 +273,7 @@ export namespace mplot protected: //! Common code to call after the vertices have been set up. - void postVertexInit() final + void postVertexInit() { auto _glfn = this->get_glfn (this->parentVis); if (this->vbos == nullptr) { @@ -310,17 +309,11 @@ export namespace mplot _glfn->BindVertexArray(0); // carefully unbind } - public: -#if 0 - //! Get the GladGLContext function pointer - std::function*)> get_glfn; -#endif - protected: //! A face for this text. The face is specfied by tfeatures.font mplot::visgl::VisualFace* face = nullptr; //! Set up a vertex buffer object - bind, buffer and set vertex array object attribute - void setupVBO (GLuint& buf, std::vector& dat, unsigned int bufferAttribPosition) final + void setupVBO (GLuint& buf, std::vector& dat, unsigned int bufferAttribPosition) { std::size_t sz = dat.size() * sizeof(float); auto _glfn = this->get_glfn (this->parentVis); @@ -329,6 +322,270 @@ export namespace mplot _glfn->VertexAttribPointer (bufferAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0)); _glfn->EnableVertexAttribArray (bufferAttribPosition); } + + + // DIVIDE + // + + + //! Set clr_text to a value suitable to be visible on the background colour bgcolour + void setVisibleOn (const std::array& bgcolour) + { + constexpr float factor = 0.85f; + this->clr_text = {1.0f - bgcolour[0] * factor, 1.0f - bgcolour[1] * factor, 1.0f - bgcolour[2] * factor}; + } + + //! Setter for VisualTextModel::viewmatrix, the model view + void setViewMatrix (const sm::mat& mv) { this->viewmatrix = mv; } + + //! Setter for VisualTextModel::scenematrix, the scene view + void setSceneMatrix (const sm::mat& sv) { this->scenematrix = sv; } + + //! Set the translation specified by \a v0 into the scene translation + template requires (N == 3) || (N == 4) + void setSceneTranslation (const sm::vec& v0) + { + this->scenematrix.set_identity(); + this->scenematrix.translate (v0); + } + + //! Set a translation (only) into the scene view matrix + template requires (N == 3) || (N == 4) + void addSceneTranslation (const sm::vec& v0) { this->scenematrix.pretranslate (v0); } + + //! Set a rotation (only) into the scene view matrix + void setSceneRotation (const sm::quaternion& r) + { + auto _offset = this->scenematrix.translation(); + this->scenematrix.set_identity(); + this->scenematrix.translate (_offset); + this->scenematrix.rotate (r); + } + + //! Add a rotation to the scene view matrix + void addSceneRotation (const sm::quaternion& r) { this->scenematrix.rotate (r); } + + //! Set a translation to the model view matrix + template requires (N == 3) || (N == 4) + void setViewTranslation (const sm::vec& v0) + { + this->viewmatrix.set_identity(); + this->viewmatrix.translate (v0); + } + + //! Add a translation to the model view matrix + void addViewTranslation (const sm::vec& v0) { this->viewmatrix.pretranslate (v0); } + + //! Set a rotation (only) into the model view matrix + void setViewRotation (const sm::quaternion& r) + { + auto tr = this->viewmatrix.translation(); + this->viewmatrix.set_identity(); + this->viewmatrix.translate (tr); + this->viewmatrix.rotate (r); + } + + //! Apply a further rotation to the model view matrix + void addViewRotation (const sm::quaternion& r) { this->viewmatrix.rotate (r); } + + + float width() const { return this->extents[1] - this->extents[0]; } + float height() const { return this->extents[3] - this->extents[2]; } + + std::string getText() const + { + std::string s = {}; + for (auto c : txt) { s += unicode::toUtf8 (c); } + return s; + } + + std::string debugText() const + { + std::stringstream ss; + for (auto c : txt) { ss << unicode::toUtf8 (c); } + ss << "--->\n" + << "parent_rotation= " << this->parent_rotation << "\n" + << "viewmatrix=\n" << this->viewmatrix << "\n" + << "scenematrix=\n" << this->scenematrix << "\n" + << "----------------------\n"; + return ss.str(); + } + + protected: + + //! Initialize the vertices that will represent the Quads. + void initializeVertices() { + + constexpr bool debug_textquads = false; + + unsigned int nquads = static_cast(this->quads.size()); + + for (unsigned int qi = 0; qi < nquads; ++qi) { + + std::array quad = this->quads[qi]; + + if constexpr (debug_textquads == true) { + std::cout << "Quad box from (" << quad[0] << "," << quad[1] << "," << quad[2] + << ") to (" << quad[3] << "," << quad[4] << "," << quad[5] + << ") to (" << quad[6] << "," << quad[7] << "," << quad[8] + << ") to (" << quad[9] << "," << quad[10] << "," << quad[11] << ")" << std::endl; + } + + this->vertex_push (quad[0], quad[1], quad[2], this->vertexPositions); //1 + this->vertex_push (quad[3], quad[4], quad[5], this->vertexPositions); //2 + this->vertex_push (quad[6], quad[7], quad[8], this->vertexPositions); //3 + this->vertex_push (quad[9], quad[10], quad[11], this->vertexPositions); //4 + + // Add the info for drawing the textures on the quads + this->vertex_push (0.0f, 1.0f, 0.0f, this->vertexTextures); + this->vertex_push (0.0f, 0.0f, 0.0f, this->vertexTextures); + this->vertex_push (1.0f, 0.0f, 0.0f, this->vertexTextures); + this->vertex_push (1.0f, 1.0f, 0.0f, this->vertexTextures); + + // All same colours + this->vertex_push (this->clr_backing, this->vertexColors); + this->vertex_push (this->clr_backing, this->vertexColors); + this->vertex_push (this->clr_backing, this->vertexColors); + this->vertex_push (this->clr_backing, this->vertexColors); + + // All same normals + this->vertex_push (0.0f, 0.0f, 1.0f, this->vertexNormals); + this->vertex_push (0.0f, 0.0f, 1.0f, this->vertexNormals); + this->vertex_push (0.0f, 0.0f, 1.0f, this->vertexNormals); + this->vertex_push (0.0f, 0.0f, 1.0f, this->vertexNormals); + + // Two triangles per quad + // qi * 4 + 1, 2 3 or 4 + uint32_t ib = (uint32_t)qi*4; + this->indices.push_back (ib++); // 0 + this->indices.push_back (ib++); // 1 + this->indices.push_back (ib); // 2 + + this->indices.push_back (ib++); // 2 + this->indices.push_back (ib); // 3 + ib -= 3; + this->indices.push_back (ib); // 0 + } + } + + public: + // A VisualTextModel may be given a name + std::string name = "VisualTextModel"; + + // The mplot::Visual ID to which I belong. max means unset. + uint32_t visual_id = std::numeric_limits::max(); + + //! The colour of the text + std::array clr_text = {0.0f, 0.0f, 0.0f}; + //! Line spacing, in multiples of the height of an 'h' + float line_spacing = 1.4f; +#if 0 + //! Parent Visual (to be replaced with a uint32_t visual_id) + mplot::VisualBase* parentVis = nullptr; + + /*! + * Callbacks are analogous to those in VisualModel + */ + std::function*)> get_shaderprogs; + //! Get the graphics shader prog id + std::function*)> get_gprog; + //! Get the text shader prog id + std::function*)> get_tprog; + + //! Set OpenGL context. Should call parentVis->setContext(). + std::function*)> setContext; + //! Release OpenGL context. Should call parentVis->releaseContext(). + std::function*)> releaseContext; + + //! SSBOs are unused in VisualTextModels, but these functions have to be present + std::function*, const unsigned int)> init_instance_data; + std::function&)> insert_instance_data; + std::function&, const float, const float)> insert_instparam_data; + std::function*)> instanced_needs_update; + + //! Setter for the parent pointer, parentVis + void set_parent (mplot::VisualBase* _vis) + { + //if (this->parentVis != nullptr) { throw std::runtime_error ("VisualTextModel: Set the parent pointer once only!"); } + this->parentVis = _vis; + } +#endif + + protected: + // The text features for this VisualTextModel + mplot::TextFeatures tfeatures; + + // face is in derived class + + //! The colour of the backing quad's vertices. Doesn't have any effect. + std::array clr_backing = {1.0f, 1.0f, 0.0f}; + + //! A scaling factor based on the desired width of an 'm' + float fontscale = 1.0f; // fontscale = tfeatures.fontsize/(float)tfeatures.fontres; + + //! A rotation of the parent model + sm::quaternion parent_rotation = {}; + + //! The text-model-specific view matrix and a scene matrix + sm::mat viewmatrix = {}; + //! Before, I wrote: We protect the scene matrix as updating it with the parent + //! model's scene matrix likely involves also adding an additional + //! translation. Now, I'm still slightly confused as to whether I *need* to have a + //! copy of the scenematrix *here*. + sm::mat scenematrix = {}; + + //! The text string stored for debugging + std::basic_string txt; + //! The Quads that form the 'medium' for the text textures. 12 float = 4 corners + std::vector> quads = {}; + //! left, right, top and bottom extents of the text for this + //! VisualTextModel. setupText should modify these as it sets up quads. Order of + //! numbers is left, right, bottom, top + sm::vec extents = { 1e7, -1e7, 1e7, -1e7 }; + //! The texture ID for each quad - so that we draw the right texture image over each quad. + std::vector quad_ids = {}; + //! Position within vertex buffer object (if I use an array of VBO) + enum VBOPos { posnVBO, normVBO, colVBO, idxVBO, textureVBO, numVBO }; + //! The OpenGL Vertex Array Object + uint32_t vao = 0; + //! Single vbo to use as in example + uint32_t vbo = 0; + //! Vertex Buffer Objects stored in an array + std::unique_ptr vbos; + //! CPU-side data for indices + std::vector indices = {}; + //! CPU-side data for quad vertex positions + std::vector vertexPositions = {}; + //! CPU-side data for quad vertex normals + std::vector vertexNormals = {}; + //! CPU-side data for vertex colours + std::vector vertexColors = {}; + //! data for textures + std::vector vertexTextures = {}; + //! A model-wide alpha value for the shader + float alpha = 1.0f; + //! If true, then calls to VisualModel::render should return + bool hide = false; + + //! Push three floats onto the vector of floats \a vp + void vertex_push (const float& x, const float& y, const float& z, std::vector& vp) + { + vp.push_back (x); + vp.push_back (y); + vp.push_back (z); + } + //! Push array of 3 floats onto the vector of floats \a vp + void vertex_push (const std::array& arr, std::vector& vp) + { + vp.push_back (arr[0]); + vp.push_back (arr[1]); + vp.push_back (arr[2]); + } + //! Push mplot::vec of 3 floats onto the vector of floats \a vp + void vertex_push (const sm::vec& vec, std::vector& vp) + { + std::copy (vec.begin(), vec.end(), std::back_inserter (vp)); + } }; } // namespace mplot diff --git a/mplot/VisualTextModelBase.h b/mplot/VisualTextModelBase.h deleted file mode 100644 index ee94363b..00000000 --- a/mplot/VisualTextModelBase.h +++ /dev/null @@ -1,328 +0,0 @@ -/*! - * \file - * - * Declares a base class for VisualTextModels. - * - * \author Seb James - * \date March 2025 - */ -module; - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -export module mplot.visualtextmodelbase; - -import mplot.visualcommon; -import :textgeometry; -import :textfeatures; - -import sm.quaternion; -import sm.mat; -import sm.vec; - -export namespace mplot -{ - //! Forward declaration of a VisualBase class - template class VisualBase; - - /*! - * This is the base class for VisualTextModel containing common code, but no GL function calls. - */ - template - struct VisualTextModelBase - { - //! Pass just the TextFeatures. parentVis, tshader etc, accessed by callbacks - VisualTextModelBase (mplot::TextFeatures _tfeatures) - { - this->tfeatures = _tfeatures; - this->fontscale = tfeatures.fontsize / static_cast(tfeatures.fontres); - } - - virtual ~VisualTextModelBase() {} - - //! Render the VisualTextModel - virtual void render() = 0; - - //! Set clr_text to a value suitable to be visible on the background colour bgcolour - void setVisibleOn (const std::array& bgcolour) - { - constexpr float factor = 0.85f; - this->clr_text = {1.0f - bgcolour[0] * factor, 1.0f - bgcolour[1] * factor, 1.0f - bgcolour[2] * factor}; - } - - //! Setter for VisualTextModel::viewmatrix, the model view - void setViewMatrix (const sm::mat& mv) { this->viewmatrix = mv; } - - //! Setter for VisualTextModel::scenematrix, the scene view - void setSceneMatrix (const sm::mat& sv) { this->scenematrix = sv; } - - //! Set the translation specified by \a v0 into the scene translation - template requires (N == 3) || (N == 4) - void setSceneTranslation (const sm::vec& v0) - { - this->scenematrix.set_identity(); - this->scenematrix.translate (v0); - } - - //! Set a translation (only) into the scene view matrix - template requires (N == 3) || (N == 4) - void addSceneTranslation (const sm::vec& v0) { this->scenematrix.pretranslate (v0); } - - //! Set a rotation (only) into the scene view matrix - void setSceneRotation (const sm::quaternion& r) - { - auto _offset = this->scenematrix.translation(); - this->scenematrix.set_identity(); - this->scenematrix.translate (_offset); - this->scenematrix.rotate (r); - } - - //! Add a rotation to the scene view matrix - void addSceneRotation (const sm::quaternion& r) { this->scenematrix.rotate (r); } - - //! Set a translation to the model view matrix - template requires (N == 3) || (N == 4) - void setViewTranslation (const sm::vec& v0) - { - this->viewmatrix.set_identity(); - this->viewmatrix.translate (v0); - } - - //! Add a translation to the model view matrix - void addViewTranslation (const sm::vec& v0) { this->viewmatrix.pretranslate (v0); } - - //! Set a rotation (only) into the model view matrix - void setViewRotation (const sm::quaternion& r) - { - auto tr = this->viewmatrix.translation(); - this->viewmatrix.set_identity(); - this->viewmatrix.translate (tr); - this->viewmatrix.rotate (r); - } - - //! Apply a further rotation to the model view matrix - void addViewRotation (const sm::quaternion& r) { this->viewmatrix.rotate (r); } - - //! Compute the geometry for a sample text. - virtual mplot::TextGeometry getTextGeometry (const std::string& _txt) = 0; - - //! Return the geometry for the stored txt - virtual mplot::TextGeometry getTextGeometry() = 0; - - float width() const { return this->extents[1] - this->extents[0]; } - float height() const { return this->extents[3] - this->extents[2]; } - - std::string getText() const - { - std::string s = {}; - for (auto c : txt) { s += unicode::toUtf8 (c); } - return s; - } - - std::string debugText() const - { - std::stringstream ss; - for (auto c : txt) { ss << unicode::toUtf8 (c); } - ss << "--->\n" - << "parent_rotation= " << this->parent_rotation << "\n" - << "viewmatrix=\n" << this->viewmatrix << "\n" - << "scenematrix=\n" << this->scenematrix << "\n" - << "----------------------\n"; - return ss.str(); - } - - protected: - static constexpr bool debug_textquads = false; - - //! Initialize the vertices that will represent the Quads. - void initializeVertices() { - - unsigned int nquads = static_cast(this->quads.size()); - - for (unsigned int qi = 0; qi < nquads; ++qi) { - - std::array quad = this->quads[qi]; - - if constexpr (debug_textquads == true) { - std::cout << "Quad box from (" << quad[0] << "," << quad[1] << "," << quad[2] - << ") to (" << quad[3] << "," << quad[4] << "," << quad[5] - << ") to (" << quad[6] << "," << quad[7] << "," << quad[8] - << ") to (" << quad[9] << "," << quad[10] << "," << quad[11] << ")" << std::endl; - } - - this->vertex_push (quad[0], quad[1], quad[2], this->vertexPositions); //1 - this->vertex_push (quad[3], quad[4], quad[5], this->vertexPositions); //2 - this->vertex_push (quad[6], quad[7], quad[8], this->vertexPositions); //3 - this->vertex_push (quad[9], quad[10], quad[11], this->vertexPositions); //4 - - // Add the info for drawing the textures on the quads - this->vertex_push (0.0f, 1.0f, 0.0f, this->vertexTextures); - this->vertex_push (0.0f, 0.0f, 0.0f, this->vertexTextures); - this->vertex_push (1.0f, 0.0f, 0.0f, this->vertexTextures); - this->vertex_push (1.0f, 1.0f, 0.0f, this->vertexTextures); - - // All same colours - this->vertex_push (this->clr_backing, this->vertexColors); - this->vertex_push (this->clr_backing, this->vertexColors); - this->vertex_push (this->clr_backing, this->vertexColors); - this->vertex_push (this->clr_backing, this->vertexColors); - - // All same normals - this->vertex_push (0.0f, 0.0f, 1.0f, this->vertexNormals); - this->vertex_push (0.0f, 0.0f, 1.0f, this->vertexNormals); - this->vertex_push (0.0f, 0.0f, 1.0f, this->vertexNormals); - this->vertex_push (0.0f, 0.0f, 1.0f, this->vertexNormals); - - // Two triangles per quad - // qi * 4 + 1, 2 3 or 4 - uint32_t ib = (uint32_t)qi*4; - this->indices.push_back (ib++); // 0 - this->indices.push_back (ib++); // 1 - this->indices.push_back (ib); // 2 - - this->indices.push_back (ib++); // 2 - this->indices.push_back (ib); // 3 - ib -= 3; - this->indices.push_back (ib); // 0 - } - } - - //! Common code to call after the vertices have been set up. - virtual void postVertexInit() = 0; - - public: - // A VisualTextModel may be given a name - std::string name = "VisualTextModel"; - - // The mplot::Visual ID to which I belong. max means unset. - uint32_t visual_id = std::numeric_limits::max(); - - //! The colour of the text - std::array clr_text = {0.0f, 0.0f, 0.0f}; - //! Line spacing, in multiples of the height of an 'h' - float line_spacing = 1.4f; -#if 0 - //! Parent Visual (to be replaced with a uint32_t visual_id) - mplot::VisualBase* parentVis = nullptr; - - /*! - * Callbacks are analogous to those in VisualModel - */ - std::function*)> get_shaderprogs; - //! Get the graphics shader prog id - std::function*)> get_gprog; - //! Get the text shader prog id - std::function*)> get_tprog; - - //! Set OpenGL context. Should call parentVis->setContext(). - std::function*)> setContext; - //! Release OpenGL context. Should call parentVis->releaseContext(). - std::function*)> releaseContext; - - //! SSBOs are unused in VisualTextModels, but these functions have to be present - std::function*, const unsigned int)> init_instance_data; - std::function&)> insert_instance_data; - std::function&, const float, const float)> insert_instparam_data; - std::function*)> instanced_needs_update; -#endif - //! Setter for the parent pointer, parentVis - void set_parent (mplot::VisualBase* _vis) - { - //if (this->parentVis != nullptr) { throw std::runtime_error ("VisualTextModel: Set the parent pointer once only!"); } - this->parentVis = _vis; - } - - protected: - // The text features for this VisualTextModel - mplot::TextFeatures tfeatures; - - // face is in derived class - - //! The colour of the backing quad's vertices. Doesn't have any effect. - std::array clr_backing = {1.0f, 1.0f, 0.0f}; - - //! A scaling factor based on the desired width of an 'm' - float fontscale = 1.0f; // fontscale = tfeatures.fontsize/(float)tfeatures.fontres; - - //! A rotation of the parent model - sm::quaternion parent_rotation = {}; - - //! The text-model-specific view matrix and a scene matrix - sm::mat viewmatrix = {}; - //! Before, I wrote: We protect the scene matrix as updating it with the parent - //! model's scene matrix likely involves also adding an additional - //! translation. Now, I'm still slightly confused as to whether I *need* to have a - //! copy of the scenematrix *here*. - sm::mat scenematrix = {}; - - //! The text string stored for debugging - std::basic_string txt; - //! The Quads that form the 'medium' for the text textures. 12 float = 4 corners - std::vector> quads = {}; - //! left, right, top and bottom extents of the text for this - //! VisualTextModel. setupText should modify these as it sets up quads. Order of - //! numbers is left, right, bottom, top - sm::vec extents = { 1e7, -1e7, 1e7, -1e7 }; - //! The texture ID for each quad - so that we draw the right texture image over each quad. - std::vector quad_ids = {}; - //! Position within vertex buffer object (if I use an array of VBO) - enum VBOPos { posnVBO, normVBO, colVBO, idxVBO, textureVBO, numVBO }; - //! The OpenGL Vertex Array Object - uint32_t vao = 0; - //! Single vbo to use as in example - uint32_t vbo = 0; - //! Vertex Buffer Objects stored in an array - std::unique_ptr vbos; - //! CPU-side data for indices - std::vector indices = {}; - //! CPU-side data for quad vertex positions - std::vector vertexPositions = {}; - //! CPU-side data for quad vertex normals - std::vector vertexNormals = {}; - //! CPU-side data for vertex colours - std::vector vertexColors = {}; - //! data for textures - std::vector vertexTextures = {}; - //! A model-wide alpha value for the shader - float alpha = 1.0f; - //! If true, then calls to VisualModel::render should return - bool hide = false; - - //! Set up a vertex buffer object - bind, buffer and set vertex array object attribute - virtual void setupVBO (uint32_t& buf, std::vector& dat, unsigned int bufferAttribPosition) = 0; - - //! Push three floats onto the vector of floats \a vp - void vertex_push (const float& x, const float& y, const float& z, std::vector& vp) - { - vp.push_back (x); - vp.push_back (y); - vp.push_back (z); - } - //! Push array of 3 floats onto the vector of floats \a vp - void vertex_push (const std::array& arr, std::vector& vp) - { - vp.push_back (arr[0]); - vp.push_back (arr[1]); - vp.push_back (arr[2]); - } - //! Push mplot::vec of 3 floats onto the vector of floats \a vp - void vertex_push (const sm::vec& vec, std::vector& vp) - { - std::copy (vec.begin(), vec.end(), std::back_inserter (vp)); - } - }; - -} // namespace mplot From af3c1ef8f31e1c3a0b0f92c819104e4c033f68e3 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 6 Mar 2026 09:58:56 +0000 Subject: [PATCH 017/106] WIP --- mplot/CoordArrows.h | 4 ++-- mplot/Visual.h | 5 ++++- mplot/VisualFace.h | 10 +++++---- mplot/VisualModel.h | 35 ++++++++++++++------------------ mplot/VisualOwnable.h | 45 ++++++++++++++++++++++------------------- mplot/VisualResources.h | 33 ++++++++++++++++-------------- mplot/VisualTextModel.h | 21 +++++++++++-------- 7 files changed, 82 insertions(+), 71 deletions(-) diff --git a/mplot/CoordArrows.h b/mplot/CoordArrows.h index 538a40bd..5906d7fc 100644 --- a/mplot/CoordArrows.h +++ b/mplot/CoordArrows.h @@ -30,8 +30,8 @@ module; export module mplot.core:coordarrows; import mplot.visualtextmodel; -import :textfeatures; -import :visualfont; +import mplot.textfeatures; +import mplot.visualfont; import sm.vec; import sm.mat; import sm.flags; diff --git a/mplot/Visual.h b/mplot/Visual.h index a6710188..7e5d060a 100644 --- a/mplot/Visual.h +++ b/mplot/Visual.h @@ -72,9 +72,11 @@ export namespace mplot this->init_resources(); this->init_gl(); +#if 0 // To go! // Special tasks: re-bind coordArrows and title text this->bindextra (this->coordArrows); this->bindextra (this->textModel); +#endif } //! Deconstructor destroys GLFW/Qt window and deregisters access to VisualResources @@ -160,6 +162,7 @@ export namespace mplot //! Obtain the window pointer win_t* getWindow() { return this->window; } +#if 0 // To go /*! * Set up the passed-in VisualModel (or indeed, VisualTextModel) with functions that need access to Visual attributes. */ @@ -181,7 +184,7 @@ export namespace mplot model->insert_instance_data = &mplot::VisualOwnable::insert_instance_data; model->insert_instparam_data = &mplot::VisualOwnable::insert_instparam_data; } - +#endif /* * A note on setContext() in keepOpen/poll/waitevents/wait: * diff --git a/mplot/VisualFace.h b/mplot/VisualFace.h index 4e6ef68b..493748f3 100644 --- a/mplot/VisualFace.h +++ b/mplot/VisualFace.h @@ -177,7 +177,7 @@ import mplot.textfeatures; import sm.vec; -namespace mplot::visgl +export namespace mplot::visgl { struct VisualFace { @@ -198,6 +198,8 @@ namespace mplot::visgl VisualFace (const mplot::VisualFont _font, unsigned int fontpixels, FT_Library& ft_freetype, GladGLContext* glfn = nullptr) { + constexpr bool debug_visualface = false; + this->init_common (_font, fontpixels, ft_freetype); // How far to loop. In principle, up to 21 bits worth - that's 2097151 possible characters! @@ -259,9 +261,6 @@ namespace mplot::visgl ~VisualFace () {} - //! Set true for informational/debug messages - static constexpr bool debug_visualface = false; - //! The FT_Face that we're managing FT_Face face; @@ -272,6 +271,8 @@ namespace mplot::visgl void init_common (const mplot::VisualFont _font, unsigned int fontpixels, FT_Library& ft_freetype) { + constexpr bool debug_visualface = false; + std::string fontpath = ""; #ifdef _MSC_VER char* userprofile = getenv ("USERPROFILE"); @@ -484,6 +485,7 @@ namespace mplot::visgl template void makeTempFontFile (const std::string& fontpath, T* file_start, T* file_stop) { + constexpr bool debug_visualface = false; T* p; if (!mplot::tools::fileExists (fontpath)) { std::ofstream fout; diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index 0d4c09e4..9cf97c4b 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -53,6 +53,8 @@ import sm.flags; // Need to import common here import mplot.visualcommon; +import mplot.visualresources; +import mplot.visualtextmodel; //import mplot.core;// Can I avoid use of this in VisualModelBase? @@ -76,7 +78,7 @@ namespace mplot // Could I have a singleton that can do the work and is a separate class so taht VisualModel no // longer needs to know about VisualBase? Visual registers its identity and the shader programs // and the singleton could set context based on an id that the VisualModel contains? - template class VisualBase; + //template class VisualBase; /*! * An OpenGL model class @@ -328,13 +330,13 @@ namespace mplot return this->texts.back()->getTextGeometry(); } - void setSceneMatrixTexts (const sm::mat& sv) final + void setSceneMatrixTexts (const sm::mat& sv) { auto ti = this->texts.begin(); while (ti != this->texts.end()) { (*ti)->setSceneMatrix (sv); ti++; } } - void setSceneTranslationTexts (const sm::vec& v0) final + void setSceneTranslationTexts (const sm::vec& v0) { auto ti = this->texts.begin(); while (ti != this->texts.end()) { (*ti)->setSceneTranslation (v0); ti++; } @@ -878,8 +880,6 @@ namespace mplot void scaleViewMatrix (const float by) { this->viewmatrix.scale (by); } - virtual void setSceneMatrixTexts (const sm::mat& sv) = 0; - //! When setting the scene matrix, also have to set the text's scene matrices. void setSceneMatrix (const sm::mat& sv) { @@ -887,8 +887,6 @@ namespace mplot this->setSceneMatrixTexts (sv); } - virtual void setSceneTranslationTexts (const sm::vec& v0) = 0; - //! Set a translation into the scene and into any child texts template requires (N == 3) || (N == 4) void setSceneTranslation (const sm::vec& v0) @@ -937,8 +935,6 @@ namespace mplot this->viewmatrix.rotate (r); } - virtual void setViewRotationTexts (const sm::quaternion& r) = 0; - //! Set a rotation (only) into the view void setViewRotation (const sm::quaternion& r) { @@ -949,8 +945,6 @@ namespace mplot this->setViewRotationTexts (r); } - virtual void addViewRotationTexts (const sm::quaternion& r) = 0; - //! Apply a further rotation to the model view matrix void addViewRotation (const sm::quaternion& r) { @@ -1289,10 +1283,13 @@ namespace mplot virtual void update_instance_data (const sm::vvec>& points, const sm::vvec& data, std::size_t i_s, std::size_t i_e) = 0; #endif - //! Setter for the parent pointer, parentVis - void set_parent (mplot::VisualBase* _vis) + + //! Setter for the parent ID, parentVis + void set_parent (const uint32_t _vis) { - if (this->parentVis != nullptr) { throw std::runtime_error ("VisualModel: Set the parent pointer once only!"); } + if (this->parentVis != std::numeric_limits::max()) { + throw std::runtime_error ("VisualModel: Set the parent pointer once only!"); + } this->parentVis = _vis; } @@ -1410,14 +1407,15 @@ namespace mplot //! A model-wide alpha value for the shader float alpha = 1.0f; - // The mplot::VisualBase in which this model exists. - mplot::VisualBase* parentVis = nullptr; + // The mplot::VisualBase in which this model exists. (visual_id) + //mplot::VisualBase* parentVis = nullptr; + uint32_t parentVis = std::numeric_limits::max(); //! A vector of pointers to text models that should be rendered. std::vector>> texts; //! Set up a vertex buffer object - bind, buffer and set vertex array object attribute - void setupVBO (GLuint& buf, std::vector& dat, unsigned int bufferAttribPosition) final + void setupVBO (GLuint& buf, std::vector& dat, unsigned int bufferAttribPosition) { std::size_t sz = dat.size() * sizeof(float); @@ -1459,9 +1457,6 @@ namespace mplot vp.emplace_back (vec[2]); } - //! Set up a vertex buffer object - bind, buffer and set vertex array object attribute - virtual void setupVBO (GLuint& buf, std::vector& dat, unsigned int bufferAttribPosition) = 0; - protected: /*! * Add the given meshgroup to this VisualModel diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index 537eae46..6fa93f40 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -59,8 +59,8 @@ module; export module mplot.core:visualownable; -import :visualcommon; -import :visualresources; +import mplot.visualcommon; +import mplot.visualresources; import mplot.visualtextmodel; import mplot.textgeometry; import mplot.textfeatures; @@ -175,7 +175,7 @@ export namespace mplot }; /*! - * VisualOwnable - adds multi-context-safe GL calls to the 'scene' base class, VisualBase + * VisualOwnable - An ownable 'scene' base class. * * This class assumes that GL functions have been loaded by the GLAD header system as a * GladGLContext pointer, which is called glfn here. GL function calls are glfn->Clear for @@ -246,7 +246,7 @@ export namespace mplot } protected: - void freetype_init() final + void freetype_init() { // Now make sure that Freetype is set up (we assume that caller code has set the correct OpenGL context) mplot::VisualResources::i().freetype_init (this, this->glfn); @@ -272,7 +272,7 @@ export namespace mplot this->freetype_init(); this->visual_id = mplot::VisualResources::i().register_visual (this->glfn); } - +#if 0 // Hopefully this will go /*! * Set up the passed-in VisualModel (or indeed, VisualTextModel) with functions that need access to Visual attributes. @@ -286,6 +286,8 @@ export namespace mplot model->get_tprog = &mplot::VisualBase::get_tprog; model->instanced_needs_update = &mplot::VisualBase::instanced_needs_update; } +#endif + /*! * Add a VisualModel to the scene as a unique_ptr. The Visual object takes ownership of the * unique_ptr. The index into Visual::vm is returned. @@ -294,6 +296,7 @@ export namespace mplot unsigned int addVisualModelId (std::unique_ptr& model) { std::unique_ptr> vmp = std::move(model); + vmp->set_parent (this->visual_id); if (vmp->instanced()) { this->state.set (visual_state::haveInstanced, true); } this->vm.push_back (std::move(vmp)); unsigned int rtn = (this->vm.size()-1); @@ -308,6 +311,7 @@ export namespace mplot T* addVisualModel (std::unique_ptr& model) { std::unique_ptr> vmp = std::move(model); + vmp->set_parent (this->visual_id); if (vmp->instanced()) { this->state.set (visual_state::haveInstanced, true); } this->vm.push_back (std::move(vmp)); return static_cast(this->vm.back().get()); @@ -334,7 +338,7 @@ export namespace mplot for (unsigned int modelId = 0; modelId < this->vm.size(); ++modelId) { if (this->vm[modelId].get() == vm_to_follow) { this->followedVM = this->vm[modelId].get(); - this->followedLastViewMatrix = this->followedVM->getViewMatrix(); // COULD pass mat4 + this->followedLastViewMatrix = this->followedVM->getViewMatrix(); break; } } @@ -371,8 +375,7 @@ export namespace mplot void set_cursorpos (double _x, double _y) { this->cursorpos = {static_cast(_x), static_cast(_y)}; } //! A callback function - static void callback_render (mplot::VisualBase* _v) { _v->render(); }; - + static void callback_render (mplot::VisualOwnable* _v) { _v->render(); }; //! GLAD OpenGL function context pointer GladGLContext* glfn = nullptr; @@ -560,12 +563,13 @@ export namespace mplot return v0; } +#if 0 // glfn always got from VisualResources now //! Glad MX specific callback - static GladGLContext* get_glfn (mplot::VisualBase* _v) + static GladGLContext* get_glfn (const uint32_t _v) { return reinterpret_cast*>(_v)->glfn; }; - +#endif protected: // GLAD specific gl context creation/freeing. GladGLContext is a struct containing GladGLContext* create_gladgl_context (const GLADloadfunc procaddressfn) @@ -594,7 +598,7 @@ export namespace mplot this->free_gladgl_context (this->glfn); } } - +#if 0 // is going... // Note: We have to have both VisualOwnable::bindmodel AND Visual::bindmodel (which calls VisualBase::bindmodel) template void bindmodel (std::unique_ptr& model) @@ -609,7 +613,7 @@ export namespace mplot model->insert_instance_data = &mplot::VisualOwnable::insert_instance_data; model->insert_instparam_data = &mplot::VisualOwnable::insert_instparam_data; } - +#endif //! Add a label _text to the scene at position _toffset. Font features are //! defined by the tfeatures. Return geometry of the text. mplot::TextGeometry addLabel (const std::string& _text, @@ -660,10 +664,9 @@ export namespace mplot return tm->getTextGeometry(); } - static unsigned int init_instance_data (mplot::VisualBase* _v, const unsigned int n_to_reserve) + static unsigned int init_instance_data (mplot::VisualOwnable* _v, const unsigned int n_to_reserve) { - auto __v = reinterpret_cast*>(_v); - unsigned int reservation = mplot::VisualResources::i().init_instance_ssbo (__v->glfn, n_to_reserve); + unsigned int reservation = mplot::VisualResources::i().init_instance_ssbo (_v->glfn, n_to_reserve); return reservation; } @@ -765,13 +768,13 @@ export namespace mplot std::vector proj2d_shader_progs; //! Stores the info required to load the text shader std::vector text_shader_progs; - +#if 0 // To go // These static functions will be set as callbacks in each VisualModel object. - static mplot::visgl::visual_shaderprogs get_shaderprogs (mplot::VisualBase* _v) { return _v->shaders; }; - static GLuint get_gprog (mplot::VisualBase* _v) { return _v->shaders.gprog; }; - static GLuint get_tprog (mplot::VisualBase* _v) { return _v->shaders.tprog; }; - - static void instanced_needs_update (mplot::VisualBase* _v) { _v->instancedNeedsUpdate (true); } + static mplot::visgl::visual_shaderprogs get_shaderprogs (mplot::VisualOwnable* _v) { return _v->shaders; }; + static GLuint get_gprog (mplot::VisualOwnable* _v) { return _v->shaders.gprog; }; + static GLuint get_tprog (mplot::VisualOwnable* _v) { return _v->shaders.tprog; }; + static void instanced_needs_update (mplot::VisualOwnable* _v) { _v->instancedNeedsUpdate (true); } +#endif //! The colour of ambient and diffuse light sources sm::vec light_colour = { 1.0f, 1.0f, 1.0f }; diff --git a/mplot/VisualResources.h b/mplot/VisualResources.h index eaae0c52..79bb2cc5 100644 --- a/mplot/VisualResources.h +++ b/mplot/VisualResources.h @@ -4,6 +4,8 @@ * Declares a VisualResource class to hold the information about Freetype and any other * one-per-program resources. * + * Importantly, holds some OpenGL state, especially the GL function pointers for each window. + * * \author Seb James * \date November 2020 */ @@ -21,6 +23,7 @@ module; #include #include FT_FREETYPE_H +#include #include #include #include @@ -30,10 +33,10 @@ module; #include #include -export module mplot.core:visualresources; +export module mplot.visualresources; -import mplot.visualfont; import mplot.visualface; +import mplot.visualfont; import mplot.textfeatures; import sm.vec; @@ -56,14 +59,14 @@ export namespace mplot for (auto& ft : this->freetypes) { FT_Done_FreeType (ft.second); } } - //! The collection of VisualFaces generated for this instance of the - //! application. Create one VisualFace for each unique combination of VisualFont - //! and fontpixels (the texture resolution) - std::map*>, + //! The collection of VisualFaces generated for this instance of the application. Create one + //! VisualFace for each unique combination of VisualFont and fontpixels (the texture + //! resolution). uint32_t is the 'visual_id' an ID of the Visual instance. + std::map, std::unique_ptr> faces; - //! FreeType library object - std::map*, FT_Library> freetypes; + //! FreeType library object. Keyed by the 'visual_id' an ID of the Visual instance. + std::map freetypes; public: VisualResources(const VisualResources&) = delete; @@ -77,7 +80,7 @@ export namespace mplot //! window). Thus, arguably, the FT_Library should be a member of mplot::Visual, //! but that's a task for the future, as I coded it this way under the false //! assumption that I'd only need one FT_Library. - void freetype_init (mplot::VisualBase* _vis, GladGLContext* glfn = nullptr) + void freetype_init (uint32_t _vis, GladGLContext* glfn = nullptr) { FT_Library freetype = nullptr; try { @@ -98,9 +101,9 @@ export namespace mplot //! When a mplot::Visual goes out of scope, its freetype library instance should be //! deinitialized. - void freetype_deinit (mplot::VisualBase* _vis) + void freetype_deinit (uint32_t _vis) { - // First clear the faces associated with VisualBase<>* _vis + // First clear the faces associated with Visual with ID _vis this->clearVisualFaces (_vis); // Second, clean up the FreeType library instance and erase from this->freetypes auto freetype = this->freetypes.find (_vis); @@ -124,7 +127,7 @@ export namespace mplot //! Return a pointer to a VisualFace for the given \a font at the given texture //! resolution, \a fontpixels and the given window (i.e. OpenGL context) \a _win. mplot::visgl::VisualFace* getVisualFace (mplot::VisualFont font, unsigned int fontpixels, - mplot::VisualBase* _vis, GladGLContext* glfn) + uint32_t _vis, GladGLContext* glfn) { mplot::visgl::VisualFace* rtn = nullptr; auto key = std::make_tuple(font, fontpixels, _vis); @@ -138,18 +141,18 @@ export namespace mplot } mplot::visgl::VisualFace* getVisualFace (const mplot::TextFeatures& tf, - mplot::VisualBase* _vis, GladGLContext* glfn) + uint32_t _vis, GladGLContext* glfn) { return this->getVisualFace (tf.font, tf.fontres, _vis, glfn); } //! Loop through this->faces clearing out those associated with the given mplot::Visual - void clearVisualFaces (mplot::VisualBase* _vis) final + void clearVisualFaces (uint32_t _vis) { auto f = this->faces.begin(); while (f != this->faces.end()) { // f->first is a key. If its third, Visual<>* element == _vis, then delete and erase - if (std::get*>(f->first) == _vis) { + if (std::get(f->first) == _vis) { f = this->faces.erase (f); } else { f++; } } diff --git a/mplot/VisualTextModel.h b/mplot/VisualTextModel.h index c7a472b6..effde058 100644 --- a/mplot/VisualTextModel.h +++ b/mplot/VisualTextModel.h @@ -10,6 +10,14 @@ */ module; +#if defined __gl3_h_ || defined __gl_h_ +// GL headers have been externally included +#else +// Include GLAD header +# define GLAD_GL_IMPLEMENTATION +# include +#endif + #include #include #include @@ -22,14 +30,16 @@ module; #include #include +#include #include #include export module mplot.visualtextmodel; +import mplot.visualresources; import mplot.visualcommon; -import mplot.textgeometry; -import mplot.textfeatures; +export import mplot.textgeometry; +export import mplot.textfeatures; import mplot.visualface; import sm.quaternion; @@ -39,7 +49,7 @@ import sm.vec; export namespace mplot { //! Forward declaration of a VisualBase class - template class VisualBase; + //template class VisualBase; /*! * This is the base class for VisualTextModel containing common code, but no GL function calls. @@ -323,11 +333,6 @@ export namespace mplot _glfn->EnableVertexAttribArray (bufferAttribPosition); } - - // DIVIDE - // - - //! Set clr_text to a value suitable to be visible on the background colour bgcolour void setVisibleOn (const std::array& bgcolour) { From 40c7d8f6e76da4eac16bde6fa3e2e390c2233c63 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 6 Mar 2026 12:47:58 +0000 Subject: [PATCH 018/106] Compiles to objects now - just got to figure out linking --- mplot/CoordArrows.h | 182 +++++++++++++++++++++------ mplot/Visual.h | 36 ++---- mplot/VisualModel.h | 270 ++++++++++++++-------------------------- mplot/VisualOwnable.h | 139 ++++++--------------- mplot/VisualResources.h | 128 ++++++++++++++++--- mplot/VisualTextModel.h | 46 +++---- mplot/win_t.h | 2 +- 7 files changed, 421 insertions(+), 382 deletions(-) diff --git a/mplot/CoordArrows.h b/mplot/CoordArrows.h index 5906d7fc..2328e842 100644 --- a/mplot/CoordArrows.h +++ b/mplot/CoordArrows.h @@ -41,9 +41,6 @@ export namespace mplot // State/options flags enum class ca_bools : uint32_t { postVertexInitRequired, hide }; - //! Forward declaration of a Visual class - //template class VisualBase; - //! This class creates the vertices for a set of coordinate arrows to be rendered //! in a 3-D scene. template @@ -78,6 +75,57 @@ export namespace mplot } sm::flags flags = flags_defaults(); + // The hide attribute accessors + void setHide (const bool _h = true) { this->flags.set (ca_bools::hide, _h); } + void toggleHide() { this->flags.flip (ca_bools::hide); } + float hidden() const { return this->flags.test (ca_bools::hide); } + + void setSceneMatrixTexts (const sm::mat& sv) + { + auto ti = this->texts.begin(); + while (ti != this->texts.end()) { (*ti)->setSceneMatrix (sv); ti++; } + } + + //! When setting the scene matrix, also have to set the text's scene matrices. + void setSceneMatrix (const sm::mat& sv) + { + this->scenematrix = sv; + this->setSceneMatrixTexts (sv); + } + + void setSceneTranslationTexts (const sm::vec& v0) + { + auto ti = this->texts.begin(); + while (ti != this->texts.end()) { (*ti)->setSceneTranslation (v0); ti++; } + } + + //! Set a translation into the scene and into any child texts + void setSceneTranslation (const sm::vec& v0) + { + this->scenematrix.set_identity(); + this->scenematrix.translate (v0); + this->setSceneTranslationTexts (v0); + } + + void setViewRotationTexts (const sm::quaternion& r) + { + // See VisualModel for explanation + auto ti = this->texts.begin(); + while (ti != this->texts.end()) { + (*ti)->setSceneRotation (r); + (*ti)->setViewRotation (r.invert()); + ti++; + } + } + //! Set a rotation (only) into the view + void setViewRotation (const sm::quaternion& r) + { + sm::vec<> os = this->viewmatrix.translation(); + this->viewmatrix.set_identity(); + this->viewmatrix.translate (os); + this->viewmatrix.rotate (r); + this->setViewRotationTexts (r); + } //! Make sure coord arrow colours are ok on the given background colour. Call this *after* finalize. void setColourForBackground (const std::array& bgcolour) @@ -172,6 +220,71 @@ export namespace mplot this->initAxisLabels(); } + void finalize() + { + this->initializeVertices(); + this->flags.set (ca_bools::postVertexInitRequired, true); + } + + uint32_t gprog = 0; + + void render() // not final + { + if (this->hidden() == true) { return; } + + // Execute post-vertex init at render, as GL should be available. + if (this->flags.test (ca_bools::postVertexInitRequired) == true) { this->postVertexInit(); } + + GLint prev_shader = 0; + + this->glfn->GetIntegerv (GL_CURRENT_PROGRAM, &prev_shader); + // Ensure the correct program is in play for this VisualModel + this->glfn->UseProgram (gprog); + + if (!this->indices.empty()) { + + this->glfn->PolygonMode (GL_FRONT_AND_BACK, GL_FILL); // filled not wireframe + + // It is only necessary to bind the vertex array object before rendering + // (not the vertex buffer objects) + this->glfn->BindVertexArray (this->vao); + + GLint loc_a = this->glfn->GetUniformLocation (gprog, static_cast("alpha")); + if (loc_a != -1) { this->glfn->Uniform1f (loc_a, 1.0f); } + + // The scene-view matrix + GLint loc_v = this->glfn->GetUniformLocation (gprog, static_cast("v_matrix")); + if (loc_v != -1) { this->glfn->UniformMatrix4fv (loc_v, 1, GL_FALSE, this->scenematrix.arr.data()); } + + // the model-view matrix + GLint loc_m = this->glfn->GetUniformLocation (gprog, static_cast("m_matrix")); + if (loc_m != -1) { this->glfn->UniformMatrix4fv (loc_m, 1, GL_FALSE, this->viewmatrix.arr.data()); } + + // the instance scaling matrix (applied to all instances) + GLint loc_s = this->glfn->GetUniformLocation (gprog, static_cast("s_matrix")); + constexpr auto idmat = sm::mat::identity(); + if (loc_s != -1) { this->glfn->UniformMatrix4fv (loc_s, 1, GL_FALSE, idmat.arr.data()); } + + // Draw the triangles + //GLint loc_is = this->glfn->GetUniformLocation (gprog, static_cast("instance_start")); + //GLint loc_ic = this->glfn->GetUniformLocation (gprog, static_cast("instance_count")); + //if (loc_is != -1) { this->glfn->Uniform1i (loc_is, -1); } + //if (loc_ic != -1) { this->glfn->Uniform1i (loc_ic, -1); } + this->glfn->DrawElements (GL_TRIANGLES, static_cast(this->indices.size()), GL_UNSIGNED_INT, 0); + + // Unbind the VAO + this->glfn->BindVertexArray(0); + } + mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); + + // Now render any VisualTextModels + auto ti = this->texts.begin(); + while (ti != this->texts.end()) { (*ti)->render(); ti++; } + + this->glfn->UseProgram (prev_shader); + mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); + } + //! Length multipliers that can be applied to ux, uy and uz sm::vec lengths = { 1.0f, 1.0f, 1.0f }; @@ -204,6 +317,8 @@ export namespace mplot std::string y_label = "Y"; std::string z_label = "Z"; + GladGLContext* glfn = nullptr; + protected: // The mplot::VisualBase in which this model exists. @@ -245,31 +360,27 @@ export namespace mplot //! CPU-side data for vertex colours std::vector vertexColors = {}; - GladGLContext* glfn = nullptr; - //! Common code to call after the vertices have been set up. GL has to have been initialised. void postVertexInit() { - GladGLContext* _glfn = this->glfn;// this->get_glfn (this->parentVis); - // Do gl memory allocation of vertex array once only if (this->vbos == nullptr) { // Create vertex array object - _glfn->GenVertexArrays (1, &this->vao); // Safe for OpenGL 4.4- + this->glfn->GenVertexArrays (1, &this->vao); // Safe for OpenGL 4.4- } - _glfn->BindVertexArray (this->vao); + this->glfn->BindVertexArray (this->vao); // Create the vertex buffer objects (once only) if (this->vbos == nullptr) { this->vbos = std::make_unique(this->numVBO); - _glfn->GenBuffers (this->numVBO, this->vbos.get()); // OpenGL 4.4- safe + this->glfn->GenBuffers (this->numVBO, this->vbos.get()); // OpenGL 4.4- safe } // Set up the indices buffer - bind and buffer the data in this->indices - _glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos[this->idxVBO]); + this->glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos[this->idxVBO]); std::size_t sz = this->indices.size() * sizeof(uint32_t); - _glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices.data(), GL_STATIC_DRAW); + this->glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices.data(), GL_STATIC_DRAW); // Binds data from the "C++ world" to the OpenGL shader world for // "position", "normalin" and "color" @@ -279,8 +390,8 @@ export namespace mplot this->setupVBO (this->vbos[this->colVBO], this->vertexColors, visgl::colLoc); // Unbind only the vertex array (not the buffers, that causes GL_INVALID_ENUM errors) - _glfn->BindVertexArray(0); // carefully unbind and rebind - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + this->glfn->BindVertexArray(0); // carefully unbind and rebind + mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); this->flags.set (ca_bools::postVertexInitRequired, false); // Maybe just a bool here } @@ -306,24 +417,21 @@ export namespace mplot */ void reinit_buffers() { - GladGLContext* _glfn = this->glfn; // this->get_glfn(this->parentVis); - // Note that we do not worry about setting context here, we assume the parent Visual has the context - if (this->flags.test (ca_bools::postVertexInitRequired) == true) { this->postVertexInit(); } // Now re-set up the VBOs - _glfn->BindVertexArray (this->vao); // carefully unbind and rebind - _glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos[this->idxVBO]); // carefully unbind and rebind + this->glfn->BindVertexArray (this->vao); // carefully unbind and rebind + this->glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos[this->idxVBO]); // carefully unbind and rebind std::size_t sz = this->indices.size() * sizeof(uint32_t); - _glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices.data(), GL_STATIC_DRAW); + this->glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices.data(), GL_STATIC_DRAW); this->setupVBO (this->vbos[this->posnVBO], this->vertexPositions, visgl::posnLoc); this->setupVBO (this->vbos[this->normVBO], this->vertexNormals, visgl::normLoc); this->setupVBO (this->vbos[this->colVBO], this->vertexColors, visgl::colLoc); - _glfn->BindVertexArray(0); // carefully unbind and rebind - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); // carefully unbind and rebind + this->glfn->BindVertexArray(0); // carefully unbind and rebind + mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); // carefully unbind and rebind } //! A vector of pointers to text models that should be rendered. @@ -334,24 +442,24 @@ export namespace mplot { std::size_t sz = dat.size() * sizeof(float); - GladGLContext* _glfn = this->glfn; // this->get_glfn(this->parentVis); - _glfn->BindBuffer (GL_ARRAY_BUFFER, buf); - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); - _glfn->BufferData (GL_ARRAY_BUFFER, sz, dat.data(), GL_STATIC_DRAW); - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); - _glfn->VertexAttribPointer (bufferAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0)); - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); - _glfn->EnableVertexAttribArray (bufferAttribPosition); - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + this->glfn->BindBuffer (GL_ARRAY_BUFFER, buf); + mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); + this->glfn->BufferData (GL_ARRAY_BUFFER, sz, dat.data(), GL_STATIC_DRAW); + mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); + this->glfn->VertexAttribPointer (bufferAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0)); + mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); + this->glfn->EnableVertexAttribArray (bufferAttribPosition); + mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); } - //! Push three floats onto the vector of floats \a vp void vertex_push (const float& x, const float& y, const float& z, std::vector& vp) - { - vp.emplace_back (x); - vp.emplace_back (y); - vp.emplace_back (z); - } + { vp.emplace_back (x); vp.emplace_back (y); vp.emplace_back (z); } + template requires (N == 3 || N == 4) + void vertex_push (const std::array& arr, std::vector& vp) + { vp.emplace_back (arr[0]); vp.emplace_back (arr[1]); vp.emplace_back (arr[2]); } + template requires (N == 3 || N == 4) + void vertex_push (const sm::vec& vec, std::vector& vp) + { vp.emplace_back (vec[0]); vp.emplace_back (vec[1]); vp.emplace_back (vec[2]); } /*! * Sphere, 1 colour version. diff --git a/mplot/Visual.h b/mplot/Visual.h index 7e5d060a..6037397b 100644 --- a/mplot/Visual.h +++ b/mplot/Visual.h @@ -29,11 +29,10 @@ module; export module mplot.core:visual; -export import :win_t; +export import mplot.win_t; +import mplot.visualresources; export import :visualglfw; export import :visualownable; -import :visualbase; -import :visualresources; export namespace mplot { @@ -70,7 +69,8 @@ export namespace mplot this->options.set (visual_options::versionStdout, _version_stdout); this->init_resources(); - this->init_gl(); + this->init_gl(); // could this come before init_resources? NO, because init_gl has + // VisualTextModel stuff that requires init_resources. Could maybe split init_gl #if 0 // To go! // Special tasks: re-bind coordArrows and title text @@ -98,9 +98,10 @@ export namespace mplot // Set up the window that will present the OpenGL graphics. This has to // happen BEFORE the call to VisualResources::freetype_init() this->init_window(); + // Check: when is this->shaders set up? in *init_gl*! So need a set_shaders method in VisualResouces + this->visual_id = mplot::VisualResources::i().register_visual (this->glfn, this->window); this->setContext(); // For freetype_init - this->freetype_init(); - this->visual_id = mplot::VisualResources::i().register_visual (this->glfn); + mplot::VisualResources::i().freetype_init (this->visual_id, this->glfn); this->releaseContext(); } @@ -162,29 +163,6 @@ export namespace mplot //! Obtain the window pointer win_t* getWindow() { return this->window; } -#if 0 // To go - /*! - * Set up the passed-in VisualModel (or indeed, VisualTextModel) with functions that need access to Visual attributes. - */ - template - void bindmodel (std::unique_ptr& model) - { - mplot::VisualBase::template bindmodel (model); // base class binds - this->bindextra (model); - } - - // The GL-dependent binds - template - void bindextra (std::unique_ptr& model) - { - model->setContext = &mplot::VisualBase::set_context; - model->releaseContext = &mplot::VisualBase::release_context; - model->get_glfn = &mplot::VisualOwnable::get_glfn; - model->init_instance_data = &mplot::VisualOwnable::init_instance_data; - model->insert_instance_data = &mplot::VisualOwnable::insert_instance_data; - model->insert_instparam_data = &mplot::VisualOwnable::insert_instparam_data; - } -#endif /* * A note on setContext() in keepOpen/poll/waitevents/wait: * diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index 9cf97c4b..e380ae10 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -102,85 +102,45 @@ namespace mplot VisualModel (const sm::vec _offset) { this->viewmatrix.translate (_offset); } //! destroy gl buffers in the deconstructor - ~VisualModel() // clang gives -Wdelete-non-abstract-non-virtual-dtor without virtual + virtual ~VisualModel() // clang gives -Wdelete-non-abstract-non-virtual-dtor without virtual { // Explicitly clear owned VisualTextModels this->texts.clear(); if (this->vbos != nullptr) { - if (this->visual_id == std::numeric_limits::max()) { - throw std::runtime_error ("visual_id is unset"); + GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->visual_id); + if (glfn) { + glfn->DeleteBuffers (this->numVBO, this->vbos.get()); + glfn->DeleteVertexArrays (1, &this->vao); } - GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); - _glfn->DeleteBuffers (this->numVBO, this->vbos.get()); - _glfn->DeleteVertexArrays (1, &this->vao); } } -#if 0 // Hope to get rid of bindmodel - /*! - * Set up the passed-in VisualTextModel with functions that need access to the parent Visual attributes. - */ - template - void bindmodel (std::unique_ptr& model) - { - if (this->parentVis == nullptr) { - throw std::runtime_error ("Can't bind a model, because I am not bound"); - } - model->set_parent (this->parentVis); - model->get_shaderprogs = &mplot::VisualBase::get_shaderprogs; - model->get_gprog = &mplot::VisualBase::get_gprog; - model->get_tprog = &mplot::VisualBase::get_tprog; - - model->get_glfn = &mplot::VisualOwnable::get_glfn; - - model->setContext = &mplot::VisualBase::set_context; - model->releaseContext = &mplot::VisualBase::release_context; - } - - /*! - * Set up the passed-in VisualTextModel with functions that need access to the parent Visual attributes. - */ - template - void bindmodel (std::unique_ptr& model) - { - if (this->parentVis == nullptr) { - throw std::runtime_error ("Can't bind a model, because I am not bound"); - } - model->set_parent (this->parentVis); - model->get_shaderprogs = &mplot::VisualBase::get_shaderprogs; - model->get_gprog = &mplot::VisualBase::get_gprog; - model->get_tprog = &mplot::VisualBase::get_tprog; - model->setContext = &mplot::VisualBase::set_context; - model->releaseContext = &mplot::VisualBase::release_context; - } -#endif - //! Common code to call after the vertices have been set up. GL has to have been initialised. void postVertexInit() { if (this->visual_id == std::numeric_limits::max()) { throw std::runtime_error ("visual_id is unset"); } - GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); + GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->visual_id); // Do gl memory allocation of vertex array once only if (this->vbos == nullptr) { // Create vertex array object - _glfn->GenVertexArrays (1, &this->vao); // Safe for OpenGL 4.4- + glfn->GenVertexArrays (1, &this->vao); // Safe for OpenGL 4.4- } - _glfn->BindVertexArray (this->vao); + glfn->BindVertexArray (this->vao); // Create the vertex buffer objects (once only) if (this->vbos == nullptr) { this->vbos = std::make_unique(this->numVBO); - _glfn->GenBuffers (this->numVBO, this->vbos.get()); // OpenGL 4.4- safe + glfn->GenBuffers (this->numVBO, this->vbos.get()); // OpenGL 4.4- safe } // Set up the indices buffer - bind and buffer the data in this->indices - _glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos[this->idxVBO]); + glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos[this->idxVBO]); std::size_t sz = this->indices.size() * sizeof(GLuint); - _glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices.data(), GL_STATIC_DRAW); + glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices.data(), GL_STATIC_DRAW); // Binds data from the "C++ world" to the OpenGL shader world for // "position", "normalin" and "color" @@ -190,13 +150,13 @@ namespace mplot this->setupVBO (this->vbos[this->colVBO], this->vertexColors, visgl::colLoc); // Unbind only the vertex array (not the buffers, that causes GL_INVALID_ENUM errors) - _glfn->BindVertexArray(0); // carefully unbind and rebind - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + glfn->BindVertexArray(0); // carefully unbind and rebind + mplot::gl::Util::checkError (__FILE__, __LINE__, glfn); - if (this->flags.test (vm_bools::instanced) && this->init_instance_data) { + if (this->flags.test (vm_bools::instanced)) { // Here, we cause the SSBOs to be intialized if they haven't already, and we reserve // some space in the SSBOs for *this model* - this->instance_start = this->init_instance_data (this->parentVis, this->max_instances); + this->instance_start = mplot::VisualResources::i().init_instance_ssbo (this->parentVis, this->max_instances); if (this->instance_start == std::numeric_limits::max()) { throw std::runtime_error ("Failed to reserve space in SSBO"); } @@ -207,20 +167,20 @@ namespace mplot */ if (this->flags.test (vm_bools::compute_bb)) { - if (this->vbos_bb == nullptr) { _glfn->GenVertexArrays (1, &this->vao_bb); } - _glfn->BindVertexArray (this->vao_bb); + if (this->vbos_bb == nullptr) { glfn->GenVertexArrays (1, &this->vao_bb); } + glfn->BindVertexArray (this->vao_bb); // Create the vertex buffer objects (once only) if (this->vbos_bb == nullptr) { this->vbos_bb = std::make_unique(this->numVBO); - _glfn->GenBuffers (this->numVBO, this->vbos_bb.get()); + glfn->GenBuffers (this->numVBO, this->vbos_bb.get()); } // Set up the indices buffer - bind and buffer the data in this->indices - _glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos_bb[this->idxVBO]); + glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos_bb[this->idxVBO]); std::size_t sz = this->indices_bb.size() * sizeof(GLuint); - _glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices_bb.data(), GL_STATIC_DRAW); + glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices_bb.data(), GL_STATIC_DRAW); // Binds data from the "C++ world" to the OpenGL shader world for // "position", "normalin" and "color" @@ -230,8 +190,8 @@ namespace mplot this->setupVBO (this->vbos_bb[this->colVBO], this->vcol_bb, visgl::colLoc); // Unbind only the vertex array (not the buffers, that causes GL_INVALID_ENUM errors) - _glfn->BindVertexArray(0); // carefully unbind and rebind - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + glfn->BindVertexArray(0); // carefully unbind and rebind + mplot::gl::Util::checkError (__FILE__, __LINE__, glfn); } this->flags.set (vm_bools::postVertexInitRequired, false); @@ -254,8 +214,9 @@ namespace mplot */ std::unique_ptr> makeVisualTextModel(const mplot::TextFeatures& tfeatures) { + // No longer really worth having, as there is only the make_unique call auto tmup = std::make_unique> (tfeatures); - this->bindmodel (tmup); + //this->bindmodel (tmup); return tmup; } @@ -269,11 +230,11 @@ namespace mplot const sm::vec& _toffset, const mplot::TextFeatures& tfeatures = mplot::TextFeatures()) { - if (this->get_shaderprogs(this->parentVis).tprog == 0) { + if (mplot::VisualResources::i().get_tprog (this->parentVis) == 0) { throw std::runtime_error ("No text shader prog. Did your VisualModel-derived class set it up?"); } - if (this->setContext != nullptr) { this->setContext (this->parentVis); } // For VisualTextModel + mplot::VisualResources::i().setContext (this->parentVis); // For VisualTextModel auto tmup = this->makeVisualTextModel (tfeatures); @@ -289,7 +250,7 @@ namespace mplot this->texts.push_back (std::move(tmup)); // As this is a setup function, release the context - if (this->releaseContext != nullptr) { this->releaseContext (this->parentVis); } + mplot::VisualResources::i().releaseContext(); return this->texts.back()->getTextGeometry(); } @@ -304,11 +265,11 @@ namespace mplot mplot::VisualTextModel*& tm, const mplot::TextFeatures& tfeatures = mplot::TextFeatures()) { - if (this->get_shaderprogs(this->parentVis).tprog == 0) { + if (mplot::VisualResources::i().get_tprog (this->parentVis) == 0) { throw std::runtime_error ("No text shader prog. Did your VisualModel-derived class set it up?"); } - if (this->setContext != nullptr) { this->setContext (this->parentVis); } // For VisualTextModel + mplot::VisualResources::i().setContext (this->parentVis); // For VisualTextModel auto tmup = this->makeVisualTextModel (tfeatures); @@ -325,7 +286,7 @@ namespace mplot tm = this->texts.back().get(); // As this is a setup function, release the context - if (this->releaseContext != nullptr) { this->releaseContext (this->parentVis); } + mplot::VisualResources::i().releaseContext(); return this->texts.back()->getTextGeometry(); } @@ -388,57 +349,51 @@ namespace mplot */ void reinit_buffers() { - if (this->visual_id == std::numeric_limits::max()) { - throw std::runtime_error ("visual_id is unset"); - } - GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); + GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->parentVis); - if (this->setContext != nullptr) { this->setContext (this->parentVis); } + mplot::VisualResources::i().setContext (this->parentVis); if (this->flags.test (vm_bools::postVertexInitRequired) == true) { this->postVertexInit(); } // Now re-set up the VBOs - _glfn->BindVertexArray (this->vao); // carefully unbind and rebind - _glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos[this->idxVBO]); // carefully unbind and rebind + glfn->BindVertexArray (this->vao); // carefully unbind and rebind + glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos[this->idxVBO]); // carefully unbind and rebind std::size_t sz = this->indices.size() * sizeof(GLuint); - _glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices.data(), GL_STATIC_DRAW); + glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices.data(), GL_STATIC_DRAW); this->setupVBO (this->vbos[this->posnVBO], this->vertexPositions, visgl::posnLoc); this->setupVBO (this->vbos[this->normVBO], this->vertexNormals, visgl::normLoc); this->setupVBO (this->vbos[this->colVBO], this->vertexColors, visgl::colLoc); - _glfn->BindVertexArray(0); // carefully unbind and rebind - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); // carefully unbind and rebind + glfn->BindVertexArray(0); // carefully unbind and rebind + mplot::gl::Util::checkError (__FILE__, __LINE__, glfn); // carefully unbind and rebind // Optional bounding box if (this->flags.test (vm_bools::compute_bb)) { - _glfn->BindVertexArray (this->vao_bb); - _glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos_bb[this->idxVBO]); + glfn->BindVertexArray (this->vao_bb); + glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos_bb[this->idxVBO]); std::size_t sz = this->indices_bb.size() * sizeof(GLuint); - _glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices_bb.data(), GL_STATIC_DRAW); + glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices_bb.data(), GL_STATIC_DRAW); this->setupVBO (this->vbos_bb[this->posnVBO], this->vpos_bb, visgl::posnLoc); this->setupVBO (this->vbos_bb[this->normVBO], this->vnorm_bb, visgl::normLoc); this->setupVBO (this->vbos_bb[this->colVBO], this->vcol_bb, visgl::colLoc); - _glfn->BindVertexArray(0); - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + glfn->BindVertexArray(0); + mplot::gl::Util::checkError (__FILE__, __LINE__, glfn); } } //! reinit ONLY vertexColors buffer void reinit_colour_buffer() { - if (this->setContext != nullptr) { this->setContext (this->parentVis); } + mplot::VisualResources::i().setContext (this->parentVis); if (this->flags.test (vm_bools::postVertexInitRequired) == true) { this->postVertexInit(); } - if (this->visual_id == std::numeric_limits::max()) { - throw std::runtime_error ("visual_id is unset"); - } - GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); + GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->parentVis); // Now re-set up the VBOs - _glfn->BindVertexArray (this->vao); // carefully unbind and rebind + glfn->BindVertexArray (this->vao); // carefully unbind and rebind this->setupVBO (this->vbos[this->colVBO], this->vertexColors, visgl::colLoc); - _glfn->BindVertexArray(0); // carefully unbind and rebind - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + glfn->BindVertexArray(0); // carefully unbind and rebind + mplot::gl::Util::checkError (__FILE__, __LINE__, glfn); } void clearTexts() { this->texts.clear(); } @@ -465,9 +420,7 @@ namespace mplot //! Re-create the model - called after updating data void reinit() { - if (this->setContext != nullptr) { - this->setContext (this->parentVis); - } + mplot::VisualResources::i().setContext (this->parentVis); // Fixme: Better not to clear, then repeatedly pushback here: this->vertexPositions.clear(); this->vertexNormals.clear(); @@ -495,7 +448,7 @@ namespace mplot */ void reinit_with_clearTexts() { - if (this->setContext != nullptr) { this->setContext (this->parentVis); } + mplot::VisualResources::i().setContext (this->parentVis); this->vertexPositions.clear(); this->vertexNormals.clear(); this->vertexColors.clear(); @@ -771,13 +724,13 @@ namespace mplot */ void finalize() { - if (this->setContext != nullptr) { this->setContext (this->parentVis); } + mplot::VisualResources::i().setContext (this->parentVis); this->initializeVertices(); this->update_bb(); this->flags.set (vm_bools::postVertexInitRequired, true); // Release context after creating and finalizing this VisualModel. On Visual::render(), // context will be re-acquired. - if (this->releaseContext != nullptr) { this->releaseContext (this->parentVis); } + mplot::VisualResources::i().releaseContext(); } static constexpr bool debug_render = false; @@ -792,42 +745,40 @@ namespace mplot GLint prev_shader = 0; - if (this->visual_id == std::numeric_limits::max()) { - throw std::runtime_error ("visual_id is unset"); - } - GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); - _glfn->GetIntegerv (GL_CURRENT_PROGRAM, &prev_shader); + GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->parentVis); + glfn->GetIntegerv (GL_CURRENT_PROGRAM, &prev_shader); // Ensure the correct program is in play for this VisualModel - _glfn->UseProgram (this->get_gprog(this->parentVis)); + uint32_t gprog = mplot::VisualResources::i().get_gprog (this->parentVis); + glfn->UseProgram (gprog); if (!this->indices.empty()) { // Enable/disable wireframe mode per-model on each render call if (this->flags.test (vm_bools::wireframe)) { - _glfn->PolygonMode (GL_FRONT_AND_BACK, GL_LINE); + glfn->PolygonMode (GL_FRONT_AND_BACK, GL_LINE); } else { - _glfn->PolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glfn->PolygonMode (GL_FRONT_AND_BACK, GL_FILL); } // It is only necessary to bind the vertex array object before rendering // (not the vertex buffer objects) - _glfn->BindVertexArray (this->vao); + glfn->BindVertexArray (this->vao); // Pass this->float to GLSL so the model can have an alpha value. - GLint loc_a = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("alpha")); - if (loc_a != -1) { _glfn->Uniform1f (loc_a, this->alpha); } + GLint loc_a = glfn->GetUniformLocation (gprog, static_cast("alpha")); + if (loc_a != -1) { glfn->Uniform1f (loc_a, this->alpha); } // The scene-view matrix - GLint loc_v = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("v_matrix")); - if (loc_v != -1) { _glfn->UniformMatrix4fv (loc_v, 1, GL_FALSE, this->scenematrix.arr.data()); } + GLint loc_v = glfn->GetUniformLocation (gprog, static_cast("v_matrix")); + if (loc_v != -1) { glfn->UniformMatrix4fv (loc_v, 1, GL_FALSE, this->scenematrix.arr.data()); } // the model-view matrix - GLint loc_m = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("m_matrix")); - if (loc_m != -1) { _glfn->UniformMatrix4fv (loc_m, 1, GL_FALSE, this->viewmatrix.arr.data()); } + GLint loc_m = glfn->GetUniformLocation (gprog, static_cast("m_matrix")); + if (loc_m != -1) { glfn->UniformMatrix4fv (loc_m, 1, GL_FALSE, this->viewmatrix.arr.data()); } // the instance scaling matrix (applied to all instances) - GLint loc_s = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("s_matrix")); - if (loc_s != -1) { _glfn->UniformMatrix4fv (loc_s, 1, GL_FALSE, this->instscale.arr.data()); } + GLint loc_s = glfn->GetUniformLocation (gprog, static_cast("s_matrix")); + if (loc_s != -1) { glfn->UniformMatrix4fv (loc_s, 1, GL_FALSE, this->instscale.arr.data()); } if constexpr (debug_render) { std::cout << "VisualModel::render: scenematrix:\n" << this->scenematrix << std::endl; @@ -835,39 +786,39 @@ namespace mplot } // Draw the triangles - GLint loc_is = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("instance_start")); - GLint loc_ic = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("instance_count")); - GLint loc_ipc = _glfn->GetUniformLocation (this->get_gprog(this->parentVis), static_cast("instparam_count")); + GLint loc_is = glfn->GetUniformLocation (gprog, static_cast("instance_start")); + GLint loc_ic = glfn->GetUniformLocation (gprog, static_cast("instance_count")); + GLint loc_ipc = glfn->GetUniformLocation (gprog, static_cast("instparam_count")); if (this->flags.test (vm_bools::instanced)) { - if (loc_is != -1) { _glfn->Uniform1i (loc_is, this->instance_start); } - if (loc_ic != -1) { _glfn->Uniform1i (loc_ic, this->instance_count); } - if (loc_ipc != -1) { _glfn->Uniform1i (loc_ipc, this->instparam_count); } - _glfn->DrawElementsInstanced (GL_TRIANGLES, static_cast(this->indices.size()), GL_UNSIGNED_INT, 0, this->instance_count); + if (loc_is != -1) { glfn->Uniform1i (loc_is, this->instance_start); } + if (loc_ic != -1) { glfn->Uniform1i (loc_ic, this->instance_count); } + if (loc_ipc != -1) { glfn->Uniform1i (loc_ipc, this->instparam_count); } + glfn->DrawElementsInstanced (GL_TRIANGLES, static_cast(this->indices.size()), GL_UNSIGNED_INT, 0, this->instance_count); } else { - if (loc_is != -1) { _glfn->Uniform1i (loc_is, -1); } - if (loc_ic != -1) { _glfn->Uniform1i (loc_ic, -1); } - _glfn->DrawElements (GL_TRIANGLES, static_cast(this->indices.size()), GL_UNSIGNED_INT, 0); + if (loc_is != -1) { glfn->Uniform1i (loc_is, -1); } + if (loc_ic != -1) { glfn->Uniform1i (loc_ic, -1); } + glfn->DrawElements (GL_TRIANGLES, static_cast(this->indices.size()), GL_UNSIGNED_INT, 0); } // Unbind the VAO - _glfn->BindVertexArray(0); + glfn->BindVertexArray(0); // Do the bounding box optionally if (this->flags.test (vm_bools::compute_bb) && this->flags.test (vm_bools::show_bb) && !this->indices_bb.empty()) { - _glfn->BindVertexArray (this->vao_bb); - _glfn->DrawElements (GL_TRIANGLES, static_cast(this->indices_bb.size()), GL_UNSIGNED_INT, 0); - _glfn->BindVertexArray(0); + glfn->BindVertexArray (this->vao_bb); + glfn->DrawElements (GL_TRIANGLES, static_cast(this->indices_bb.size()), GL_UNSIGNED_INT, 0); + glfn->BindVertexArray(0); } } - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + mplot::gl::Util::checkError (__FILE__, __LINE__, glfn); // Now render any VisualTextModels - _glfn->PolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glfn->PolygonMode (GL_FRONT_AND_BACK, GL_FILL); auto ti = this->texts.begin(); while (ti != this->texts.end()) { (*ti)->render(); ti++; } - _glfn->UseProgram (prev_shader); - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + glfn->UseProgram (prev_shader); + mplot::gl::Util::checkError (__FILE__, __LINE__, glfn); } //! Setter for the viewmatrix @@ -1190,22 +1141,6 @@ namespace mplot //! per-instance and there may be fewer than instance_count parameters) unsigned int instparam_count = 0; #if 0 - /*! - * A function that will be runtime defined to get_shaderprogs from a pointer to - * Visual (saving a boilerplate argument and avoiding that killer circular - * dependency at the cost of one line of boilerplate in client programs) - */ - std::function*)> get_shaderprogs; - //! Get the graphics shader prog id - std::function*)> get_gprog; - //! Get the text shader prog id - std::function*)> get_tprog; - - //! Set OpenGL context. Should call parentVis->setContext(). - std::function*)> setContext; - //! Release OpenGL context. Should call parentVis->releaseContext(). - std::function*)> releaseContext; - //! Init the SSBOs for instanced rendering std::function*, const unsigned int)> init_instance_data; std::function&)> insert_instance_data; @@ -1252,12 +1187,6 @@ namespace mplot if (position.size() > this->max_instances) { throw std::runtime_error ("set_instance_data: Haven't reserved enough space for that"); } - if (!this->insert_instance_data) { - throw std::runtime_error ("set_instance_data: Function insert_instance_data is not bound"); - } - if (!this->insert_instparam_data) { - throw std::runtime_error ("set_instance_data: Function insert_instparam_data is not bound"); - } if (colour.size() != scale.size() || colour.size() != alpha.size()) { throw std::runtime_error ("set_instance_data: params vvecs should all have same size (colour, rotn, scale)"); } @@ -1265,25 +1194,18 @@ namespace mplot for (size_t i = 0; i < position.size(); ++i) { // Get access to the SSBO in VisualResources and add the 3 floats in position[i] at // the location defined by this->instance_start + i - this->insert_instance_data (this->instance_start + i, position[i]); + mplot::VisualResources::i().insert_instance_data (this->instance_start + i, position[i]); } this->instance_count = position.size(); for (size_t i = 0; i < colour.size(); ++i) { - this->insert_instparam_data (this->instance_start + i, colour[i], alpha[i], scale[i]); + mplot::VisualResources::i().insert_instparam_data (this->instance_start + i, colour[i], alpha[i], scale[i]); } this->instparam_count = colour.size(); - this->instanced_needs_update (this->parentVis); + mplot::VisualResources::i().instanced_needs_update (this->parentVis); } - -#if 0 - //! Update the instance positions and params (colour, rotn, scale) in a range - virtual void update_instance_data (const sm::vvec>& points, const sm::vvec& data, - std::size_t i_s, std::size_t i_e) = 0; -#endif - //! Setter for the parent ID, parentVis void set_parent (const uint32_t _vis) { @@ -1422,15 +1344,15 @@ namespace mplot if (this->visual_id == std::numeric_limits::max()) { throw std::runtime_error ("visual_id is unset"); } - GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->visual_id); - _glfn->BindBuffer (GL_ARRAY_BUFFER, buf); - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); - _glfn->BufferData (GL_ARRAY_BUFFER, sz, dat.data(), GL_STATIC_DRAW); - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); - _glfn->VertexAttribPointer (bufferAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0)); - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); - _glfn->EnableVertexAttribArray (bufferAttribPosition); - mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); + GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->visual_id); + glfn->BindBuffer (GL_ARRAY_BUFFER, buf); + mplot::gl::Util::checkError (__FILE__, __LINE__, glfn); + glfn->BufferData (GL_ARRAY_BUFFER, sz, dat.data(), GL_STATIC_DRAW); + mplot::gl::Util::checkError (__FILE__, __LINE__, glfn); + glfn->VertexAttribPointer (bufferAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0)); + mplot::gl::Util::checkError (__FILE__, __LINE__, glfn); + glfn->EnableVertexAttribArray (bufferAttribPosition); + mplot::gl::Util::checkError (__FILE__, __LINE__, glfn); } //! Push three floats onto the vector of floats \a vp diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index 6fa93f40..687236d7 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -59,6 +59,7 @@ module; export module mplot.core:visualownable; +import mplot.win_t; import mplot.visualcommon; import mplot.visualresources; import mplot.visualtextmodel; @@ -96,7 +97,7 @@ export namespace mplot //! True means that at least one of our VisualModels is an instanced rendering model haveInstanced, //! When true, the instanced data SSBO needs to be copied to the GPU - instancedNeedsUpdate, + //instancedNeedsUpdate, (gone to VisualResources) //! Left mouse button is down mouseButtonLeftPressed, //! Right mouse button is down @@ -213,11 +214,7 @@ export namespace mplot this->init_gl(); } - // Hopefully, these will go - // A callback friendly wrapper for setContext - static void set_context (mplot::VisualOwnable* _v) { _v->setContext(); }; - // A callback friendly wrapper for releaseContext - static void release_context (mplot::VisualOwnable* _v) { _v->releaseContext(); }; + ~VisualOwnable() {} //! Deconstruct gl memory/context void deconstructCommon() @@ -226,14 +223,12 @@ export namespace mplot this->vm.clear(); // Explicitly deconstruct coordArrows, textModel and texts here this->coordArrows.reset (nullptr); - this->userFrame.reset (nullptr); this->textModel.reset (nullptr); for (auto& t : this->texts) { t.reset (nullptr); } if (this->shaders.gprog) { this->glfn->DeleteProgram (this->shaders.gprog); this->shaders.gprog = 0; - this->active_gprog = mplot::visgl::graphics_shader_type::none; } if (this->shaders.tprog) { this->glfn->DeleteProgram (this->shaders.tprog); @@ -242,17 +237,9 @@ export namespace mplot this->free_gladgl_context (this->glfn); // Free up the Fonts associated with this mplot::Visual - mplot::VisualResources::i().freetype_deinit (this); + mplot::VisualResources::i().freetype_deinit (this->visual_id); } - protected: - void freetype_init() - { - // Now make sure that Freetype is set up (we assume that caller code has set the correct OpenGL context) - mplot::VisualResources::i().freetype_init (this, this->glfn); - } - - public: // Public init that is given a context (window or widget) and then sets up the // VisualResource, shaders and so on. void init (mplot::win_t* ctx) @@ -269,24 +256,9 @@ export namespace mplot { // VisualResources provides font management and GLFW management. Ensure it exists in memory. mplot::VisualResources::i().create(); - this->freetype_init(); - this->visual_id = mplot::VisualResources::i().register_visual (this->glfn); + this->visual_id = mplot::VisualResources::i().register_visual (this->glfn, this->window); + mplot::VisualResources::i().freetype_init (this->visual_id, this->glfn); } -#if 0 - // Hopefully this will go - /*! - * Set up the passed-in VisualModel (or indeed, VisualTextModel) with functions that need access to Visual attributes. - */ - template - void bindmodel (std::unique_ptr& model) - { - model->set_parent (this); - model->get_shaderprogs = &mplot::VisualBase::get_shaderprogs; - model->get_gprog = &mplot::VisualBase::get_gprog; - model->get_tprog = &mplot::VisualBase::get_tprog; - model->instanced_needs_update = &mplot::VisualBase::instanced_needs_update; - } -#endif /*! * Add a VisualModel to the scene as a unique_ptr. The Visual object takes ownership of the @@ -377,22 +349,28 @@ export namespace mplot //! A callback function static void callback_render (mplot::VisualOwnable* _v) { _v->render(); }; - //! GLAD OpenGL function context pointer + //! GLAD OpenGL function context pointer. A copy is stored in VisualResources. GladGLContext* glfn = nullptr; //! Stores the OpenGL function context version that was loaded int glfn_version = 0; + //! Graphics context functions that refer to the window system (GLFW usually) are defined in derived class + virtual void setContext() = 0; + virtual void releaseContext() = 0; + virtual void swapBuffers() = 0; + virtual void setSwapInterval() = 0; + //! Take a screenshot of the window. Return vec containing width * height or {-1, -1} on //! failure. Set transparent_bg to get a transparent background. sm::vec saveImage (const std::string& img_filename, const bool transparent_bg = false) { this->setContext(); - GLint viewport[4]; // current viewport + int32_t viewport[4]; // current viewport this->glfn->GetIntegerv (GL_VIEWPORT, viewport); - sm::vec dims; + sm::vec dims; dims[0] = viewport[2]; dims[1] = viewport[3]; auto bits = std::make_unique(dims.product() * 4); @@ -405,20 +383,20 @@ export namespace mplot this->glfn->PixelStorei (GL_PACK_SKIP_PIXELS, 0); this->glfn->ReadPixels (0, 0, dims[0], dims[1], GL_RGBA, GL_UNSIGNED_BYTE, bits.get()); - for (int i = 0; i < dims[1]; ++i) { - int rev_line = (dims[1] - i - 1) * 4 * dims[0]; - int for_line = i * 4 * dims[0]; + for (int32_t i = 0; i < dims[1]; ++i) { + int32_t rev_line = (dims[1] - i - 1) * 4 * dims[0]; + int32_t for_line = i * 4 * dims[0]; if (transparent_bg) { - for (int j = 0; j < 4 * dims[0]; ++j) { + for (int32_t j = 0; j < 4 * dims[0]; ++j) { rbits[rev_line + j] = bits[for_line + j]; } } else { - for (int j = 0; j < 4 * dims[0]; ++j) { + for (int32_t j = 0; j < 4 * dims[0]; ++j) { rbits[rev_line + j] = (j % 4 == 3) ? 255 : bits[for_line + j]; } } } - unsigned int error = lodepng::encode (img_filename, rbits.get(), dims[0], dims[1]); + uint32_t error = lodepng::encode (img_filename, rbits.get(), dims[0], dims[1]); if (error) { std::cerr << "encoder error " << error << ": " << lodepng_error_text (error) << std::endl; dims.set_from (-1); @@ -432,14 +410,6 @@ export namespace mplot { this->setContext(); - if (this->ptype == perspective_type::orthographic || this->ptype == perspective_type::perspective) { - if (this->active_gprog != mplot::visgl::graphics_shader_type::projection2d) { - if (this->shaders.gprog) { this->glfn->DeleteProgram (this->shaders.gprog); } - this->shaders.gprog = mplot::gl::LoadShadersMX (this->proj2d_shader_progs, this->glfn); - this->active_gprog = mplot::visgl::graphics_shader_type::projection2d; - } - } // else do nothing (all current shaders are 2D perspective) - this->glfn->UseProgram (this->shaders.gprog); this->glfn->Viewport (0, 0, this->window_w * mplot::retinaScale, this->window_h * mplot::retinaScale); @@ -503,14 +473,9 @@ export namespace mplot this->coordArrows->render(); } - // Show the user frame of reference - if (this->options.test (visual_options::showUserFrame) && this->userFrame) { - this->userFrame->render(); - } - - if (this->haveInstanced() && this->instancedNeedsUpdate()) { - this->copy_instance_data_to_gpu(); - this->instancedNeedsUpdate (false); + if (this->haveInstanced() && mplot::VisualResources::i().get_instanced_needs_update (this->visual_id)) { + mplot::VisualResources::i().copy_instance_ssbo_to_gpu(); + mplot::VisualResources::i().instanced_needs_update (this->visual_id, false); } auto vmi = this->vm.begin(); @@ -563,13 +528,6 @@ export namespace mplot return v0; } -#if 0 // glfn always got from VisualResources now - //! Glad MX specific callback - static GladGLContext* get_glfn (const uint32_t _v) - { - return reinterpret_cast*>(_v)->glfn; - }; -#endif protected: // GLAD specific gl context creation/freeing. GladGLContext is a struct containing GladGLContext* create_gladgl_context (const GLADloadfunc procaddressfn) @@ -598,22 +556,7 @@ export namespace mplot this->free_gladgl_context (this->glfn); } } -#if 0 // is going... - // Note: We have to have both VisualOwnable::bindmodel AND Visual::bindmodel (which calls VisualBase::bindmodel) - template - void bindmodel (std::unique_ptr& model) - { - model->set_parent (this); - model->get_shaderprogs = &mplot::VisualBase::get_shaderprogs; - model->get_gprog = &mplot::VisualBase::get_gprog; - model->get_tprog = &mplot::VisualBase::get_tprog; - model->instanced_needs_update = &mplot::VisualBase::instanced_needs_update; - model->get_glfn = &mplot::VisualOwnable::get_glfn; - model->init_instance_data = &mplot::VisualOwnable::init_instance_data; - model->insert_instance_data = &mplot::VisualOwnable::insert_instance_data; - model->insert_instparam_data = &mplot::VisualOwnable::insert_instparam_data; - } -#endif + //! Add a label _text to the scene at position _toffset. Font features are //! defined by the tfeatures. Return geometry of the text. mplot::TextGeometry addLabel (const std::string& _text, @@ -623,7 +566,7 @@ export namespace mplot this->setContext(); if (this->shaders.tprog == 0) { throw std::runtime_error ("No text shader prog."); } auto tmup = std::make_unique> (tfeatures); - this->bindmodel (tmup); + if (tfeatures.centre_horz == true) { mplot::TextGeometry tg = tmup->getTextGeometry(_text); sm::vec centred_locn = _toffset; @@ -649,7 +592,7 @@ export namespace mplot this->setContext(); if (this->shaders.tprog == 0) { throw std::runtime_error ("No text shader prog."); } auto tmup = std::make_unique> (tfeatures); - this->bindmodel (tmup); + if (tfeatures.centre_horz == true) { mplot::TextGeometry tg = tmup->getTextGeometry(_text); sm::vec centred_locn = _toffset; @@ -663,7 +606,7 @@ export namespace mplot this->releaseContext(); return tm->getTextGeometry(); } - +#if 0 // code to use VisualResources directly static unsigned int init_instance_data (mplot::VisualOwnable* _v, const unsigned int n_to_reserve) { unsigned int reservation = mplot::VisualResources::i().init_instance_ssbo (_v->glfn, n_to_reserve); @@ -685,7 +628,7 @@ export namespace mplot { mplot::VisualResources::i().copy_instance_ssbo_to_gpu(); } - +#endif protected: // Initialize OpenGL shaders, set some flags (Alpha, Anti-aliasing), read in any external // state from json, and set up the coordinate arrows and any VisualTextModels that will be @@ -709,7 +652,7 @@ export namespace mplot {GL_FRAGMENT_SHADER, "Visual.frag.glsl", mplot::getDefaultFragShader(glver), 0 } }; this->shaders.gprog = mplot::gl::LoadShadersMX (this->proj2d_shader_progs, this->glfn); - this->active_gprog = mplot::visgl::graphics_shader_type::projection2d; + mplot::VisualResources::i().set_gprog (this->visual_id, this->shaders.gprog); // A specific text shader is loaded for text rendering this->text_shader_progs = { @@ -717,6 +660,7 @@ export namespace mplot {GL_FRAGMENT_SHADER, "VisText.frag.glsl" , mplot::getDefaultTextFragShader(glver), 0 } }; this->shaders.tprog = mplot::gl::LoadShadersMX (this->text_shader_progs, this->glfn); + mplot::VisualResources::i().set_tprog (this->visual_id, this->shaders.tprog); // OpenGL options this->glfn->Enable (GL_DEPTH_TEST); @@ -729,10 +673,8 @@ export namespace mplot // Use coordArrowsOffset to set the location of the CoordArrows *scene* this->coordArrows = std::make_unique>(); - // For CoordArrows, because we don't add via Visual::addVisualModel(), we - // have to set the get_shaderprogs function here: - this->bindmodel (this->coordArrows); // Won't need bindmodel - this->coordArrows->glfn = this->glfn; // Just copy in + this->coordArrows->glfn = this->glfn; + this->coordArrows->gprog = this->shaders.gprog; // And NOW we can proceed to init (lengths, thickness, em size for labels): this->coordArrows->init (sm::vec<>{0.1f, 0.1f, 0.1f}, 1.0f, 0.01f); @@ -745,7 +687,7 @@ export namespace mplot // Set up the title, which may or may not be rendered mplot::TextFeatures title_tf(0.035f, 64); this->textModel = std::make_unique> (title_tf); - this->bindmodel (this->textModel); + this->textModel->setSceneTranslation ({0.0f, 0.0f, 0.0f}); this->textModel->setupText (this->title); @@ -761,9 +703,8 @@ export namespace mplot //! The OpenGL shader programs have an integer ID and are stored in a simple struct. There's //! one for graphical objects and a text shader program, which uses textures to draw text on //! quads. - mplot::visgl::visual_shaderprogs shaders; - //! Which shader is active for graphics shading. In practice, this is always 'projection2d' - mplot::visgl::graphics_shader_type active_gprog = mplot::visgl::graphics_shader_type::none; + mplot::visgl::visual_shaderprogs shaders; // stored in VisualResources too. + //! Stores the info required to load the 2D projection shader std::vector proj2d_shader_progs; //! Stores the info required to load the text shader @@ -773,7 +714,7 @@ export namespace mplot static mplot::visgl::visual_shaderprogs get_shaderprogs (mplot::VisualOwnable* _v) { return _v->shaders; }; static GLuint get_gprog (mplot::VisualOwnable* _v) { return _v->shaders.gprog; }; static GLuint get_tprog (mplot::VisualOwnable* _v) { return _v->shaders.tprog; }; - static void instanced_needs_update (mplot::VisualOwnable* _v) { _v->instancedNeedsUpdate (true); } + static void instanced_needs_update (mplot::VisualOwnable* _v) { _v->instancedNeedsUpdate (true); } //next #endif //! The colour of ambient and diffuse light sources @@ -868,9 +809,9 @@ export namespace mplot //! True if one of our added VisualModels is an instanced model bool haveInstanced() const { return this->state.test (visual_state::haveInstanced); } - //! Does our instanced data need to be pushed over to the GPU during render()? - bool instancedNeedsUpdate() const { return this->state.test (visual_state::instancedNeedsUpdate); } - void instancedNeedsUpdate (const bool val) { this->state.set (visual_state::instancedNeedsUpdate, val); } + //! Does our instanced data need to be pushed over to the GPU during render()? Now stored in VisualResources + //bool instancedNeedsUpdate() const { return this->state.test (visual_state::instancedNeedsUpdate); } + //void instancedNeedsUpdate (const bool val) { this->state.set (visual_state::instancedNeedsUpdate, val); } /* * User-settable projection values for the near clipping distance, the far clipping distance diff --git a/mplot/VisualResources.h b/mplot/VisualResources.h index 79bb2cc5..702f4aad 100644 --- a/mplot/VisualResources.h +++ b/mplot/VisualResources.h @@ -19,6 +19,11 @@ module; # include #endif +#ifndef _glfw3_h_ +# define GLFW_INCLUDE_NONE +# include +#endif + // FreeType for text rendering #include #include FT_FREETYPE_H @@ -27,17 +32,17 @@ module; #include #include #include -#include - #include #include #include export module mplot.visualresources; +import mplot.visualcommon; import mplot.visualface; import mplot.visualfont; import mplot.textfeatures; +import mplot.win_t; import sm.vec; @@ -141,51 +146,142 @@ export namespace mplot } mplot::visgl::VisualFace* getVisualFace (const mplot::TextFeatures& tf, - uint32_t _vis, GladGLContext* glfn) + const uint32_t _vis, GladGLContext* glfn) { return this->getVisualFace (tf.font, tf.fontres, _vis, glfn); } //! Loop through this->faces clearing out those associated with the given mplot::Visual - void clearVisualFaces (uint32_t _vis) + void clearVisualFaces (const uint32_t _vis) { + mplot::VisualFont thefont; + unsigned int fpixels = 0; + uint32_t vf_vis = std::numeric_limits::max(); + auto f = this->faces.begin(); + while (f != this->faces.end()) { - // f->first is a key. If its third, Visual<>* element == _vis, then delete and erase - if (std::get(f->first) == _vis) { + // f->first is a key. If its third, visual_id element == _vis, then delete and erase + // f->first needs unpacking; want 3rd elemetn + std::tie(thefont, fpixels, vf_vis) = f->first; + + if (vf_vis == _vis) { f = this->faces.erase (f); } else { f++; } } } - uint32_t register_visual (GladGLContext* glfn) + uint32_t next_visual_id = 0; + + // GL function context pointers used in the program, keyed by a uint32_t ID + std::map visual_keyed_gladglcontexts; + // GL shader programs used by Visual in the program, keyed by ID + std::map visual_keyed_shaderprogs; + // Window contexts + std::map visual_keyed_windows; + // Does instanced data need update? + std::map visual_keyed_instanced_needs_update; + + // win_t is GLFWwindow and this is really 'struct GLFWwindow' so we need it to be properly defined + uint32_t register_visual (GladGLContext* glfn, mplot::win_t* win) { uint32_t visual_id = this->next_visual_id++; - visual_gladglcontexts[visual_id] = glfn; + this->visual_keyed_gladglcontexts[visual_id] = glfn; + this->visual_keyed_shaderprogs[visual_id] = {}; // initialized empty with 0s + this->visual_keyed_windows[visual_id] = win; + this->visual_keyed_instanced_needs_update[visual_id] = false; return visual_id; } - uint32_t next_visual_id = 0; - - // Pointers to Visuals in the program, keyed by a uint32_t ID - std::map visual_gladglcontexts; + // Return true if there is a GladGLContext for visual_id + bool test_glfn (const uint32_t visual_id) + { + if (visual_id == std::numeric_limits::max()) { + return false; + } + try { + [[maybe_unused]] GladGLContext* glfn = this->visual_keyed_gladglcontexts.at (visual_id); + return true; + } catch (const std::exception& e) {} + return false; + } // A VisualModel can call this, passing in the numeric ID of the context it belongs to and // this will pass back the correct GL context pointer. - GladGLContext* get_glfn (uint32_t visual_id) + GladGLContext* get_glfn (const uint32_t visual_id) noexcept { - // somehow set context from visual_pointers[visual_id]->setContext(); - GladGLContext* glfn = visual_gladglcontexts[visual_id]; + if (visual_id == std::numeric_limits::max()) { return nullptr; } + GladGLContext* glfn = this->visual_keyed_gladglcontexts[visual_id]; return glfn; } + void set_tprog (const uint32_t visual_id, const uint32_t _tprog) + { + if (visual_id == std::numeric_limits::max()) { + throw std::runtime_error ("VisualResources::set_tprog(): visual_id is unset"); + } + this->visual_keyed_shaderprogs[visual_id].tprog = _tprog; + } + + uint32_t get_tprog (const uint32_t visual_id) + { + if (visual_id == std::numeric_limits::max()) { + throw std::runtime_error ("VisualResources::get_tprog(): visual_id is unset"); + } + return this->visual_keyed_shaderprogs[visual_id].tprog; + } + + void set_gprog (const uint32_t visual_id, const uint32_t _gprog) + { + if (visual_id == std::numeric_limits::max()) { + throw std::runtime_error ("VisualResources::set_gprog(): visual_id is unset"); + } + this->visual_keyed_shaderprogs[visual_id].gprog = _gprog; + } + + uint32_t get_gprog (const uint32_t visual_id) + { + if (visual_id == std::numeric_limits::max()) { + throw std::runtime_error ("VisualResources::get_gprog(): visual_id is unset"); + } + return this->visual_keyed_shaderprogs[visual_id].gprog; + } + + // Better in VisualGlfw? Or should what's in VisualGlfw come in here? + void setContext (const uint32_t visual_id) + { + if (visual_id == std::numeric_limits::max()) { + throw std::runtime_error ("VisualResources::setContext(): visual_id is unset"); + } + glfwMakeContextCurrent (this->visual_keyed_windows[visual_id]); + } + + void releaseContext() { glfwMakeContextCurrent (nullptr); } + + bool get_instanced_needs_update (const uint32_t visual_id) + { + if (visual_id == std::numeric_limits::max()) { + throw std::runtime_error ("VisualResources::get_instanced_needs_update: visual_id is unset"); + } + return this->visual_keyed_instanced_needs_update[visual_id]; + } + + void instanced_needs_update (const uint32_t visual_id, const bool val = true) + { + if (visual_id == std::numeric_limits::max()) { + throw std::runtime_error ("VisualResources::instanced_needs_update: visual_id is unset"); + } + this->visual_keyed_instanced_needs_update[visual_id] = val; + } + /*! * We also manage some programm-wide SSBO objects for instanced rendering * VisualResourcesdata in . Reserve n_to_reserve instances of data in the SSBOs. Return the * start offset into the buffers in terms of number of instances */ - unsigned int init_instance_ssbo (GladGLContext* glfn, const unsigned int n_to_reserve) + unsigned int init_instance_ssbo (const uint32_t visual_id, const unsigned int n_to_reserve) { + GladGLContext* glfn = this->get_glfn (visual_id); unsigned int reservation = std::numeric_limits::max(); if constexpr (mplot::gl::version::has_ssbo (glver) == true) { if (this->instance_data.ready() == false) { this->instance_data.init (glfn); } diff --git a/mplot/VisualTextModel.h b/mplot/VisualTextModel.h index effde058..bd7453d3 100644 --- a/mplot/VisualTextModel.h +++ b/mplot/VisualTextModel.h @@ -67,8 +67,10 @@ export namespace mplot ~VisualTextModel() { if (this->vbos != nullptr) { - this->get_glfn(this->parentVis)->DeleteBuffers (this->numVBO, this->vbos.get()); - this->get_glfn(this->parentVis)->DeleteVertexArrays (1, &this->vao); + // To be a visualresources get + GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->parentVis); + _glfn->DeleteBuffers (this->numVBO, this->vbos.get()); + _glfn->DeleteVertexArrays (1, &this->vao); } } @@ -78,9 +80,8 @@ export namespace mplot if (this->hide == true) { return; } GLint prev_shader; - GLuint tshaderprog = this->get_tprog (this->parentVis); - - auto _glfn = this->get_glfn (this->parentVis); + GLuint tshaderprog = mplot::VisualResources::i().get_tprog (this->parentVis); + GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->parentVis); _glfn->GetIntegerv (GL_CURRENT_PROGRAM, &prev_shader); @@ -120,20 +121,15 @@ export namespace mplot mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn); } -#if 0 - //! Get the GladGLContext function pointer - std::function*)> get_glfn; -#endif - //! Compute the geometry for a sample text. mplot::TextGeometry getTextGeometry (const std::string& _txt) { mplot::TextGeometry geom; - if (!this->get_glfn) { return geom; } + if (!mplot::VisualResources::i().test_glfn (this->parentVis)) { return geom; } if (this->face == nullptr) { - this->face = VisualResources::i().getVisualFace (this->tfeatures, this->parentVis, - this->get_glfn(this->parentVis)); + GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->parentVis); + this->face = VisualResources::i().getVisualFace (this->tfeatures, this->parentVis, _glfn); } // First convert string from ASCII/UTF-8 into Unicode. @@ -154,10 +150,10 @@ export namespace mplot { mplot::TextGeometry geom; - if (!this->get_glfn) { return geom; } + if (!mplot::VisualResources::i().test_glfn (this->parentVis)) { return geom; } if (this->face == nullptr) { - this->face = VisualResources::i().getVisualFace (this->tfeatures, this->parentVis, - this->get_glfn(this->parentVis)); + GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->parentVis); + this->face = VisualResources::i().getVisualFace (this->tfeatures, this->parentVis, _glfn); } for (std::basic_string::const_iterator c = this->txt.begin(); c != this->txt.end(); c++) { @@ -208,8 +204,8 @@ export namespace mplot constexpr bool debug_textquads = false; if (this->face == nullptr) { - this->face = VisualResources::i().getVisualFace (this->tfeatures, this->parentVis, - this->get_glfn(this->parentVis)); + GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->parentVis); + this->face = VisualResources::i().getVisualFace (this->tfeatures, this->parentVis, _glfn); } this->txt = _txt; @@ -285,7 +281,7 @@ export namespace mplot //! Common code to call after the vertices have been set up. void postVertexInit() { - auto _glfn = this->get_glfn (this->parentVis); + GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->parentVis); if (this->vbos == nullptr) { // Create vertex array object _glfn->GenVertexArrays (1, &this->vao); // Safe for OpenGL 4.4- @@ -326,13 +322,14 @@ export namespace mplot void setupVBO (GLuint& buf, std::vector& dat, unsigned int bufferAttribPosition) { std::size_t sz = dat.size() * sizeof(float); - auto _glfn = this->get_glfn (this->parentVis); + GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->parentVis); _glfn->BindBuffer (GL_ARRAY_BUFFER, buf); _glfn->BufferData (GL_ARRAY_BUFFER, sz, dat.data(), GL_STATIC_DRAW); _glfn->VertexAttribPointer (bufferAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0)); _glfn->EnableVertexAttribArray (bufferAttribPosition); } + public: //! Set clr_text to a value suitable to be visible on the background colour bgcolour void setVisibleOn (const std::array& bgcolour) { @@ -477,17 +474,14 @@ export namespace mplot // A VisualTextModel may be given a name std::string name = "VisualTextModel"; - // The mplot::Visual ID to which I belong. max means unset. - uint32_t visual_id = std::numeric_limits::max(); - //! The colour of the text std::array clr_text = {0.0f, 0.0f, 0.0f}; //! Line spacing, in multiples of the height of an 'h' float line_spacing = 1.4f; -#if 0 - //! Parent Visual (to be replaced with a uint32_t visual_id) - mplot::VisualBase* parentVis = nullptr; + //! Parent Visual. The mplot::Visual ID to which I belong. max means unset. + uint32_t parentVis = std::numeric_limits::max(); +#if 0 /*! * Callbacks are analogous to those in VisualModel */ diff --git a/mplot/win_t.h b/mplot/win_t.h index 7c26997d..c5343ea5 100644 --- a/mplot/win_t.h +++ b/mplot/win_t.h @@ -5,7 +5,7 @@ module; # include #endif // _glfw3_h_ -export module mplot.core:win_t; +export module mplot.win_t; export namespace mplot { From c4f305a1ee75440f0f39b609138713c9b367ea8e Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 6 Mar 2026 14:16:39 +0000 Subject: [PATCH 019/106] Compile glad as a lib and link --- CMakeLists.txt | 2 +- examples/CMakeLists.txt | 2 +- mplot/CoordArrows.h | 4 +- mplot/VisualFace.h | 4 +- mplot/VisualModel.h | 4 +- mplot/VisualOwnable.h | 8 - mplot/VisualResources.h | 8 +- mplot/VisualTextModel.h | 4 +- mplot/gl/shaders.h | 6 + mplot/glad/CMakeLists.txt | 4 + mplot/glad/gl.c | 1336 +++++++++ mplot/glad/gl.h | 5917 +++++++------------------------------ mplot/glad/khrplatform.h | 311 ++ 13 files changed, 2744 insertions(+), 4866 deletions(-) create mode 100644 mplot/glad/gl.c create mode 100644 mplot/glad/khrplatform.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e17ea207..eb1ddd7a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.28.5) -project(mathplot LANGUAGES CXX) +project(mathplot LANGUAGES CXX C) # Note that the project version is encoded in mplot/version.h and not in this CMakeLists.txt message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}") diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 394e6b60..c59b9bab 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -67,7 +67,7 @@ target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE ${PROJECT_SOURCE_DIR}/maths/sm/geometry ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra ${PROJECT_SOURCE_DIR}/maths/sm/vvec) -target_link_libraries(helloworld OpenGL::GL glfw Freetype::Freetype) +target_link_libraries(helloworld OpenGL::GL glfw Freetype::Freetype glad) add_executable(rod rod.cpp) target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} diff --git a/mplot/CoordArrows.h b/mplot/CoordArrows.h index 2328e842..0eb6322e 100644 --- a/mplot/CoordArrows.h +++ b/mplot/CoordArrows.h @@ -11,9 +11,7 @@ module; #if defined __gl3_h_ || defined __gl_h_ // could get a fuller list from glfw.h // GL headers appear to have been externally included. #else -// Include GLAD header -# define GLAD_GL_IMPLEMENTATION -# include +# include #endif // GL headers #include diff --git a/mplot/VisualFace.h b/mplot/VisualFace.h index 493748f3..3f7149ca 100644 --- a/mplot/VisualFace.h +++ b/mplot/VisualFace.h @@ -14,9 +14,7 @@ module; #if defined __gl3_h_ || defined __gl_h_ // GL headers have been externally included #else -// Include GLAD header -# define GLAD_GL_IMPLEMENTATION -# include +# include #endif // FreeType for text rendering diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index e380ae10..c8d02e84 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -15,9 +15,7 @@ #if defined __gl3_h_ || defined __gl_h_ // GL headers have been externally included #else -// Include GLAD header -# define GLAD_GL_IMPLEMENTATION -# include +# include #endif #include diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index 687236d7..3d805b46 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -16,14 +16,6 @@ */ module; -#if defined __gl3_h_ || defined __gl_h_ // could get a fuller list from glfw.h -// GL headers appear to have been externally included. -#else -// Include GLAD header -# define GLAD_GL_IMPLEMENTATION -# include -#endif // GL headers - #include #include #include diff --git a/mplot/VisualResources.h b/mplot/VisualResources.h index 702f4aad..398ab044 100644 --- a/mplot/VisualResources.h +++ b/mplot/VisualResources.h @@ -11,14 +11,10 @@ */ module; -#if defined __gl3_h_ || defined __gl_h_ -// GL headers have been externally included -#else // Include GLAD header -# define GLAD_GL_IMPLEMENTATION -# include -#endif +#include +// Probably DO want to separate all things GLFW into VisualGlfw. #ifndef _glfw3_h_ # define GLFW_INCLUDE_NONE # include diff --git a/mplot/VisualTextModel.h b/mplot/VisualTextModel.h index bd7453d3..4fab489c 100644 --- a/mplot/VisualTextModel.h +++ b/mplot/VisualTextModel.h @@ -13,9 +13,7 @@ module; #if defined __gl3_h_ || defined __gl_h_ // GL headers have been externally included #else -// Include GLAD header -# define GLAD_GL_IMPLEMENTATION -# include +# include #endif #include diff --git a/mplot/gl/shaders.h b/mplot/gl/shaders.h index 88fa0a17..d86cf988 100644 --- a/mplot/gl/shaders.h +++ b/mplot/gl/shaders.h @@ -9,6 +9,12 @@ * Author: Seb James. */ +#if defined __gl3_h_ || defined __gl_h_ +// GL headers have been externally included +#else +# include +#endif + #include #include #include diff --git a/mplot/glad/CMakeLists.txt b/mplot/glad/CMakeLists.txt index fb65bb6d..8e03817f 100644 --- a/mplot/glad/CMakeLists.txt +++ b/mplot/glad/CMakeLists.txt @@ -1 +1,5 @@ install(FILES gl.h gl_mx.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include/mplot/glad) + +# Build glad library here +include_directories(BEFORE ${PROJECT_SOURCE_DIR}) +add_library(glad SHARED gl.c) diff --git a/mplot/glad/gl.c b/mplot/glad/gl.c new file mode 100644 index 00000000..788d23b5 --- /dev/null +++ b/mplot/glad/gl.c @@ -0,0 +1,1336 @@ +/** + * 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 + + + + + + + + +static void glad_gl_load_GL_VERSION_1_0(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_1_0) return; + context->Accum = (PFNGLACCUMPROC) load(userptr, "glAccum"); + context->AlphaFunc = (PFNGLALPHAFUNCPROC) load(userptr, "glAlphaFunc"); + context->Begin = (PFNGLBEGINPROC) load(userptr, "glBegin"); + context->Bitmap = (PFNGLBITMAPPROC) load(userptr, "glBitmap"); + context->BlendFunc = (PFNGLBLENDFUNCPROC) load(userptr, "glBlendFunc"); + context->CallList = (PFNGLCALLLISTPROC) load(userptr, "glCallList"); + context->CallLists = (PFNGLCALLLISTSPROC) load(userptr, "glCallLists"); + context->Clear = (PFNGLCLEARPROC) load(userptr, "glClear"); + context->ClearAccum = (PFNGLCLEARACCUMPROC) load(userptr, "glClearAccum"); + context->ClearColor = (PFNGLCLEARCOLORPROC) load(userptr, "glClearColor"); + context->ClearDepth = (PFNGLCLEARDEPTHPROC) load(userptr, "glClearDepth"); + context->ClearIndex = (PFNGLCLEARINDEXPROC) load(userptr, "glClearIndex"); + context->ClearStencil = (PFNGLCLEARSTENCILPROC) load(userptr, "glClearStencil"); + context->ClipPlane = (PFNGLCLIPPLANEPROC) load(userptr, "glClipPlane"); + context->Color3b = (PFNGLCOLOR3BPROC) load(userptr, "glColor3b"); + context->Color3bv = (PFNGLCOLOR3BVPROC) load(userptr, "glColor3bv"); + context->Color3d = (PFNGLCOLOR3DPROC) load(userptr, "glColor3d"); + context->Color3dv = (PFNGLCOLOR3DVPROC) load(userptr, "glColor3dv"); + context->Color3f = (PFNGLCOLOR3FPROC) load(userptr, "glColor3f"); + context->Color3fv = (PFNGLCOLOR3FVPROC) load(userptr, "glColor3fv"); + context->Color3i = (PFNGLCOLOR3IPROC) load(userptr, "glColor3i"); + context->Color3iv = (PFNGLCOLOR3IVPROC) load(userptr, "glColor3iv"); + context->Color3s = (PFNGLCOLOR3SPROC) load(userptr, "glColor3s"); + context->Color3sv = (PFNGLCOLOR3SVPROC) load(userptr, "glColor3sv"); + context->Color3ub = (PFNGLCOLOR3UBPROC) load(userptr, "glColor3ub"); + context->Color3ubv = (PFNGLCOLOR3UBVPROC) load(userptr, "glColor3ubv"); + context->Color3ui = (PFNGLCOLOR3UIPROC) load(userptr, "glColor3ui"); + context->Color3uiv = (PFNGLCOLOR3UIVPROC) load(userptr, "glColor3uiv"); + context->Color3us = (PFNGLCOLOR3USPROC) load(userptr, "glColor3us"); + context->Color3usv = (PFNGLCOLOR3USVPROC) load(userptr, "glColor3usv"); + context->Color4b = (PFNGLCOLOR4BPROC) load(userptr, "glColor4b"); + context->Color4bv = (PFNGLCOLOR4BVPROC) load(userptr, "glColor4bv"); + context->Color4d = (PFNGLCOLOR4DPROC) load(userptr, "glColor4d"); + context->Color4dv = (PFNGLCOLOR4DVPROC) load(userptr, "glColor4dv"); + context->Color4f = (PFNGLCOLOR4FPROC) load(userptr, "glColor4f"); + context->Color4fv = (PFNGLCOLOR4FVPROC) load(userptr, "glColor4fv"); + context->Color4i = (PFNGLCOLOR4IPROC) load(userptr, "glColor4i"); + context->Color4iv = (PFNGLCOLOR4IVPROC) load(userptr, "glColor4iv"); + context->Color4s = (PFNGLCOLOR4SPROC) load(userptr, "glColor4s"); + context->Color4sv = (PFNGLCOLOR4SVPROC) load(userptr, "glColor4sv"); + context->Color4ub = (PFNGLCOLOR4UBPROC) load(userptr, "glColor4ub"); + context->Color4ubv = (PFNGLCOLOR4UBVPROC) load(userptr, "glColor4ubv"); + context->Color4ui = (PFNGLCOLOR4UIPROC) load(userptr, "glColor4ui"); + context->Color4uiv = (PFNGLCOLOR4UIVPROC) load(userptr, "glColor4uiv"); + context->Color4us = (PFNGLCOLOR4USPROC) load(userptr, "glColor4us"); + context->Color4usv = (PFNGLCOLOR4USVPROC) load(userptr, "glColor4usv"); + context->ColorMask = (PFNGLCOLORMASKPROC) load(userptr, "glColorMask"); + context->ColorMaterial = (PFNGLCOLORMATERIALPROC) load(userptr, "glColorMaterial"); + context->CopyPixels = (PFNGLCOPYPIXELSPROC) load(userptr, "glCopyPixels"); + context->CullFace = (PFNGLCULLFACEPROC) load(userptr, "glCullFace"); + context->DeleteLists = (PFNGLDELETELISTSPROC) load(userptr, "glDeleteLists"); + context->DepthFunc = (PFNGLDEPTHFUNCPROC) load(userptr, "glDepthFunc"); + context->DepthMask = (PFNGLDEPTHMASKPROC) load(userptr, "glDepthMask"); + context->DepthRange = (PFNGLDEPTHRANGEPROC) load(userptr, "glDepthRange"); + context->Disable = (PFNGLDISABLEPROC) load(userptr, "glDisable"); + context->DrawBuffer = (PFNGLDRAWBUFFERPROC) load(userptr, "glDrawBuffer"); + context->DrawPixels = (PFNGLDRAWPIXELSPROC) load(userptr, "glDrawPixels"); + context->EdgeFlag = (PFNGLEDGEFLAGPROC) load(userptr, "glEdgeFlag"); + context->EdgeFlagv = (PFNGLEDGEFLAGVPROC) load(userptr, "glEdgeFlagv"); + context->Enable = (PFNGLENABLEPROC) load(userptr, "glEnable"); + context->End = (PFNGLENDPROC) load(userptr, "glEnd"); + context->EndList = (PFNGLENDLISTPROC) load(userptr, "glEndList"); + context->EvalCoord1d = (PFNGLEVALCOORD1DPROC) load(userptr, "glEvalCoord1d"); + context->EvalCoord1dv = (PFNGLEVALCOORD1DVPROC) load(userptr, "glEvalCoord1dv"); + context->EvalCoord1f = (PFNGLEVALCOORD1FPROC) load(userptr, "glEvalCoord1f"); + context->EvalCoord1fv = (PFNGLEVALCOORD1FVPROC) load(userptr, "glEvalCoord1fv"); + context->EvalCoord2d = (PFNGLEVALCOORD2DPROC) load(userptr, "glEvalCoord2d"); + context->EvalCoord2dv = (PFNGLEVALCOORD2DVPROC) load(userptr, "glEvalCoord2dv"); + context->EvalCoord2f = (PFNGLEVALCOORD2FPROC) load(userptr, "glEvalCoord2f"); + context->EvalCoord2fv = (PFNGLEVALCOORD2FVPROC) load(userptr, "glEvalCoord2fv"); + context->EvalMesh1 = (PFNGLEVALMESH1PROC) load(userptr, "glEvalMesh1"); + context->EvalMesh2 = (PFNGLEVALMESH2PROC) load(userptr, "glEvalMesh2"); + context->EvalPoint1 = (PFNGLEVALPOINT1PROC) load(userptr, "glEvalPoint1"); + context->EvalPoint2 = (PFNGLEVALPOINT2PROC) load(userptr, "glEvalPoint2"); + context->FeedbackBuffer = (PFNGLFEEDBACKBUFFERPROC) load(userptr, "glFeedbackBuffer"); + context->Finish = (PFNGLFINISHPROC) load(userptr, "glFinish"); + context->Flush = (PFNGLFLUSHPROC) load(userptr, "glFlush"); + context->Fogf = (PFNGLFOGFPROC) load(userptr, "glFogf"); + context->Fogfv = (PFNGLFOGFVPROC) load(userptr, "glFogfv"); + context->Fogi = (PFNGLFOGIPROC) load(userptr, "glFogi"); + context->Fogiv = (PFNGLFOGIVPROC) load(userptr, "glFogiv"); + context->FrontFace = (PFNGLFRONTFACEPROC) load(userptr, "glFrontFace"); + context->Frustum = (PFNGLFRUSTUMPROC) load(userptr, "glFrustum"); + context->GenLists = (PFNGLGENLISTSPROC) load(userptr, "glGenLists"); + context->GetBooleanv = (PFNGLGETBOOLEANVPROC) load(userptr, "glGetBooleanv"); + context->GetClipPlane = (PFNGLGETCLIPPLANEPROC) load(userptr, "glGetClipPlane"); + context->GetDoublev = (PFNGLGETDOUBLEVPROC) load(userptr, "glGetDoublev"); + context->GetError = (PFNGLGETERRORPROC) load(userptr, "glGetError"); + context->GetFloatv = (PFNGLGETFLOATVPROC) load(userptr, "glGetFloatv"); + context->GetIntegerv = (PFNGLGETINTEGERVPROC) load(userptr, "glGetIntegerv"); + context->GetLightfv = (PFNGLGETLIGHTFVPROC) load(userptr, "glGetLightfv"); + context->GetLightiv = (PFNGLGETLIGHTIVPROC) load(userptr, "glGetLightiv"); + context->GetMapdv = (PFNGLGETMAPDVPROC) load(userptr, "glGetMapdv"); + context->GetMapfv = (PFNGLGETMAPFVPROC) load(userptr, "glGetMapfv"); + context->GetMapiv = (PFNGLGETMAPIVPROC) load(userptr, "glGetMapiv"); + context->GetMaterialfv = (PFNGLGETMATERIALFVPROC) load(userptr, "glGetMaterialfv"); + context->GetMaterialiv = (PFNGLGETMATERIALIVPROC) load(userptr, "glGetMaterialiv"); + context->GetPixelMapfv = (PFNGLGETPIXELMAPFVPROC) load(userptr, "glGetPixelMapfv"); + context->GetPixelMapuiv = (PFNGLGETPIXELMAPUIVPROC) load(userptr, "glGetPixelMapuiv"); + context->GetPixelMapusv = (PFNGLGETPIXELMAPUSVPROC) load(userptr, "glGetPixelMapusv"); + context->GetPolygonStipple = (PFNGLGETPOLYGONSTIPPLEPROC) load(userptr, "glGetPolygonStipple"); + context->GetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + context->GetTexEnvfv = (PFNGLGETTEXENVFVPROC) load(userptr, "glGetTexEnvfv"); + context->GetTexEnviv = (PFNGLGETTEXENVIVPROC) load(userptr, "glGetTexEnviv"); + context->GetTexGendv = (PFNGLGETTEXGENDVPROC) load(userptr, "glGetTexGendv"); + context->GetTexGenfv = (PFNGLGETTEXGENFVPROC) load(userptr, "glGetTexGenfv"); + context->GetTexGeniv = (PFNGLGETTEXGENIVPROC) load(userptr, "glGetTexGeniv"); + context->GetTexImage = (PFNGLGETTEXIMAGEPROC) load(userptr, "glGetTexImage"); + context->GetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC) load(userptr, "glGetTexLevelParameterfv"); + context->GetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC) load(userptr, "glGetTexLevelParameteriv"); + context->GetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load(userptr, "glGetTexParameterfv"); + context->GetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load(userptr, "glGetTexParameteriv"); + context->Hint = (PFNGLHINTPROC) load(userptr, "glHint"); + context->IndexMask = (PFNGLINDEXMASKPROC) load(userptr, "glIndexMask"); + context->Indexd = (PFNGLINDEXDPROC) load(userptr, "glIndexd"); + context->Indexdv = (PFNGLINDEXDVPROC) load(userptr, "glIndexdv"); + context->Indexf = (PFNGLINDEXFPROC) load(userptr, "glIndexf"); + context->Indexfv = (PFNGLINDEXFVPROC) load(userptr, "glIndexfv"); + context->Indexi = (PFNGLINDEXIPROC) load(userptr, "glIndexi"); + context->Indexiv = (PFNGLINDEXIVPROC) load(userptr, "glIndexiv"); + context->Indexs = (PFNGLINDEXSPROC) load(userptr, "glIndexs"); + context->Indexsv = (PFNGLINDEXSVPROC) load(userptr, "glIndexsv"); + context->InitNames = (PFNGLINITNAMESPROC) load(userptr, "glInitNames"); + context->IsEnabled = (PFNGLISENABLEDPROC) load(userptr, "glIsEnabled"); + context->IsList = (PFNGLISLISTPROC) load(userptr, "glIsList"); + context->LightModelf = (PFNGLLIGHTMODELFPROC) load(userptr, "glLightModelf"); + context->LightModelfv = (PFNGLLIGHTMODELFVPROC) load(userptr, "glLightModelfv"); + context->LightModeli = (PFNGLLIGHTMODELIPROC) load(userptr, "glLightModeli"); + context->LightModeliv = (PFNGLLIGHTMODELIVPROC) load(userptr, "glLightModeliv"); + context->Lightf = (PFNGLLIGHTFPROC) load(userptr, "glLightf"); + context->Lightfv = (PFNGLLIGHTFVPROC) load(userptr, "glLightfv"); + context->Lighti = (PFNGLLIGHTIPROC) load(userptr, "glLighti"); + context->Lightiv = (PFNGLLIGHTIVPROC) load(userptr, "glLightiv"); + context->LineStipple = (PFNGLLINESTIPPLEPROC) load(userptr, "glLineStipple"); + context->LineWidth = (PFNGLLINEWIDTHPROC) load(userptr, "glLineWidth"); + context->ListBase = (PFNGLLISTBASEPROC) load(userptr, "glListBase"); + context->LoadIdentity = (PFNGLLOADIDENTITYPROC) load(userptr, "glLoadIdentity"); + context->LoadMatrixd = (PFNGLLOADMATRIXDPROC) load(userptr, "glLoadMatrixd"); + context->LoadMatrixf = (PFNGLLOADMATRIXFPROC) load(userptr, "glLoadMatrixf"); + context->LoadName = (PFNGLLOADNAMEPROC) load(userptr, "glLoadName"); + context->LogicOp = (PFNGLLOGICOPPROC) load(userptr, "glLogicOp"); + context->Map1d = (PFNGLMAP1DPROC) load(userptr, "glMap1d"); + context->Map1f = (PFNGLMAP1FPROC) load(userptr, "glMap1f"); + context->Map2d = (PFNGLMAP2DPROC) load(userptr, "glMap2d"); + context->Map2f = (PFNGLMAP2FPROC) load(userptr, "glMap2f"); + context->MapGrid1d = (PFNGLMAPGRID1DPROC) load(userptr, "glMapGrid1d"); + context->MapGrid1f = (PFNGLMAPGRID1FPROC) load(userptr, "glMapGrid1f"); + context->MapGrid2d = (PFNGLMAPGRID2DPROC) load(userptr, "glMapGrid2d"); + context->MapGrid2f = (PFNGLMAPGRID2FPROC) load(userptr, "glMapGrid2f"); + context->Materialf = (PFNGLMATERIALFPROC) load(userptr, "glMaterialf"); + context->Materialfv = (PFNGLMATERIALFVPROC) load(userptr, "glMaterialfv"); + context->Materiali = (PFNGLMATERIALIPROC) load(userptr, "glMateriali"); + context->Materialiv = (PFNGLMATERIALIVPROC) load(userptr, "glMaterialiv"); + context->MatrixMode = (PFNGLMATRIXMODEPROC) load(userptr, "glMatrixMode"); + context->MultMatrixd = (PFNGLMULTMATRIXDPROC) load(userptr, "glMultMatrixd"); + context->MultMatrixf = (PFNGLMULTMATRIXFPROC) load(userptr, "glMultMatrixf"); + context->NewList = (PFNGLNEWLISTPROC) load(userptr, "glNewList"); + context->Normal3b = (PFNGLNORMAL3BPROC) load(userptr, "glNormal3b"); + context->Normal3bv = (PFNGLNORMAL3BVPROC) load(userptr, "glNormal3bv"); + context->Normal3d = (PFNGLNORMAL3DPROC) load(userptr, "glNormal3d"); + context->Normal3dv = (PFNGLNORMAL3DVPROC) load(userptr, "glNormal3dv"); + context->Normal3f = (PFNGLNORMAL3FPROC) load(userptr, "glNormal3f"); + context->Normal3fv = (PFNGLNORMAL3FVPROC) load(userptr, "glNormal3fv"); + context->Normal3i = (PFNGLNORMAL3IPROC) load(userptr, "glNormal3i"); + context->Normal3iv = (PFNGLNORMAL3IVPROC) load(userptr, "glNormal3iv"); + context->Normal3s = (PFNGLNORMAL3SPROC) load(userptr, "glNormal3s"); + context->Normal3sv = (PFNGLNORMAL3SVPROC) load(userptr, "glNormal3sv"); + context->Ortho = (PFNGLORTHOPROC) load(userptr, "glOrtho"); + context->PassThrough = (PFNGLPASSTHROUGHPROC) load(userptr, "glPassThrough"); + context->PixelMapfv = (PFNGLPIXELMAPFVPROC) load(userptr, "glPixelMapfv"); + context->PixelMapuiv = (PFNGLPIXELMAPUIVPROC) load(userptr, "glPixelMapuiv"); + context->PixelMapusv = (PFNGLPIXELMAPUSVPROC) load(userptr, "glPixelMapusv"); + context->PixelStoref = (PFNGLPIXELSTOREFPROC) load(userptr, "glPixelStoref"); + context->PixelStorei = (PFNGLPIXELSTOREIPROC) load(userptr, "glPixelStorei"); + context->PixelTransferf = (PFNGLPIXELTRANSFERFPROC) load(userptr, "glPixelTransferf"); + context->PixelTransferi = (PFNGLPIXELTRANSFERIPROC) load(userptr, "glPixelTransferi"); + context->PixelZoom = (PFNGLPIXELZOOMPROC) load(userptr, "glPixelZoom"); + context->PointSize = (PFNGLPOINTSIZEPROC) load(userptr, "glPointSize"); + context->PolygonMode = (PFNGLPOLYGONMODEPROC) load(userptr, "glPolygonMode"); + context->PolygonStipple = (PFNGLPOLYGONSTIPPLEPROC) load(userptr, "glPolygonStipple"); + context->PopAttrib = (PFNGLPOPATTRIBPROC) load(userptr, "glPopAttrib"); + context->PopMatrix = (PFNGLPOPMATRIXPROC) load(userptr, "glPopMatrix"); + context->PopName = (PFNGLPOPNAMEPROC) load(userptr, "glPopName"); + context->PushAttrib = (PFNGLPUSHATTRIBPROC) load(userptr, "glPushAttrib"); + context->PushMatrix = (PFNGLPUSHMATRIXPROC) load(userptr, "glPushMatrix"); + context->PushName = (PFNGLPUSHNAMEPROC) load(userptr, "glPushName"); + context->RasterPos2d = (PFNGLRASTERPOS2DPROC) load(userptr, "glRasterPos2d"); + context->RasterPos2dv = (PFNGLRASTERPOS2DVPROC) load(userptr, "glRasterPos2dv"); + context->RasterPos2f = (PFNGLRASTERPOS2FPROC) load(userptr, "glRasterPos2f"); + context->RasterPos2fv = (PFNGLRASTERPOS2FVPROC) load(userptr, "glRasterPos2fv"); + context->RasterPos2i = (PFNGLRASTERPOS2IPROC) load(userptr, "glRasterPos2i"); + context->RasterPos2iv = (PFNGLRASTERPOS2IVPROC) load(userptr, "glRasterPos2iv"); + context->RasterPos2s = (PFNGLRASTERPOS2SPROC) load(userptr, "glRasterPos2s"); + context->RasterPos2sv = (PFNGLRASTERPOS2SVPROC) load(userptr, "glRasterPos2sv"); + context->RasterPos3d = (PFNGLRASTERPOS3DPROC) load(userptr, "glRasterPos3d"); + context->RasterPos3dv = (PFNGLRASTERPOS3DVPROC) load(userptr, "glRasterPos3dv"); + context->RasterPos3f = (PFNGLRASTERPOS3FPROC) load(userptr, "glRasterPos3f"); + context->RasterPos3fv = (PFNGLRASTERPOS3FVPROC) load(userptr, "glRasterPos3fv"); + context->RasterPos3i = (PFNGLRASTERPOS3IPROC) load(userptr, "glRasterPos3i"); + context->RasterPos3iv = (PFNGLRASTERPOS3IVPROC) load(userptr, "glRasterPos3iv"); + context->RasterPos3s = (PFNGLRASTERPOS3SPROC) load(userptr, "glRasterPos3s"); + context->RasterPos3sv = (PFNGLRASTERPOS3SVPROC) load(userptr, "glRasterPos3sv"); + context->RasterPos4d = (PFNGLRASTERPOS4DPROC) load(userptr, "glRasterPos4d"); + context->RasterPos4dv = (PFNGLRASTERPOS4DVPROC) load(userptr, "glRasterPos4dv"); + context->RasterPos4f = (PFNGLRASTERPOS4FPROC) load(userptr, "glRasterPos4f"); + context->RasterPos4fv = (PFNGLRASTERPOS4FVPROC) load(userptr, "glRasterPos4fv"); + context->RasterPos4i = (PFNGLRASTERPOS4IPROC) load(userptr, "glRasterPos4i"); + context->RasterPos4iv = (PFNGLRASTERPOS4IVPROC) load(userptr, "glRasterPos4iv"); + context->RasterPos4s = (PFNGLRASTERPOS4SPROC) load(userptr, "glRasterPos4s"); + context->RasterPos4sv = (PFNGLRASTERPOS4SVPROC) load(userptr, "glRasterPos4sv"); + context->ReadBuffer = (PFNGLREADBUFFERPROC) load(userptr, "glReadBuffer"); + context->ReadPixels = (PFNGLREADPIXELSPROC) load(userptr, "glReadPixels"); + context->Rectd = (PFNGLRECTDPROC) load(userptr, "glRectd"); + context->Rectdv = (PFNGLRECTDVPROC) load(userptr, "glRectdv"); + context->Rectf = (PFNGLRECTFPROC) load(userptr, "glRectf"); + context->Rectfv = (PFNGLRECTFVPROC) load(userptr, "glRectfv"); + context->Recti = (PFNGLRECTIPROC) load(userptr, "glRecti"); + context->Rectiv = (PFNGLRECTIVPROC) load(userptr, "glRectiv"); + context->Rects = (PFNGLRECTSPROC) load(userptr, "glRects"); + context->Rectsv = (PFNGLRECTSVPROC) load(userptr, "glRectsv"); + context->RenderMode = (PFNGLRENDERMODEPROC) load(userptr, "glRenderMode"); + context->Rotated = (PFNGLROTATEDPROC) load(userptr, "glRotated"); + context->Rotatef = (PFNGLROTATEFPROC) load(userptr, "glRotatef"); + context->Scaled = (PFNGLSCALEDPROC) load(userptr, "glScaled"); + context->Scalef = (PFNGLSCALEFPROC) load(userptr, "glScalef"); + context->Scissor = (PFNGLSCISSORPROC) load(userptr, "glScissor"); + context->SelectBuffer = (PFNGLSELECTBUFFERPROC) load(userptr, "glSelectBuffer"); + context->ShadeModel = (PFNGLSHADEMODELPROC) load(userptr, "glShadeModel"); + context->StencilFunc = (PFNGLSTENCILFUNCPROC) load(userptr, "glStencilFunc"); + context->StencilMask = (PFNGLSTENCILMASKPROC) load(userptr, "glStencilMask"); + context->StencilOp = (PFNGLSTENCILOPPROC) load(userptr, "glStencilOp"); + context->TexCoord1d = (PFNGLTEXCOORD1DPROC) load(userptr, "glTexCoord1d"); + context->TexCoord1dv = (PFNGLTEXCOORD1DVPROC) load(userptr, "glTexCoord1dv"); + context->TexCoord1f = (PFNGLTEXCOORD1FPROC) load(userptr, "glTexCoord1f"); + context->TexCoord1fv = (PFNGLTEXCOORD1FVPROC) load(userptr, "glTexCoord1fv"); + context->TexCoord1i = (PFNGLTEXCOORD1IPROC) load(userptr, "glTexCoord1i"); + context->TexCoord1iv = (PFNGLTEXCOORD1IVPROC) load(userptr, "glTexCoord1iv"); + context->TexCoord1s = (PFNGLTEXCOORD1SPROC) load(userptr, "glTexCoord1s"); + context->TexCoord1sv = (PFNGLTEXCOORD1SVPROC) load(userptr, "glTexCoord1sv"); + context->TexCoord2d = (PFNGLTEXCOORD2DPROC) load(userptr, "glTexCoord2d"); + context->TexCoord2dv = (PFNGLTEXCOORD2DVPROC) load(userptr, "glTexCoord2dv"); + context->TexCoord2f = (PFNGLTEXCOORD2FPROC) load(userptr, "glTexCoord2f"); + context->TexCoord2fv = (PFNGLTEXCOORD2FVPROC) load(userptr, "glTexCoord2fv"); + context->TexCoord2i = (PFNGLTEXCOORD2IPROC) load(userptr, "glTexCoord2i"); + context->TexCoord2iv = (PFNGLTEXCOORD2IVPROC) load(userptr, "glTexCoord2iv"); + context->TexCoord2s = (PFNGLTEXCOORD2SPROC) load(userptr, "glTexCoord2s"); + context->TexCoord2sv = (PFNGLTEXCOORD2SVPROC) load(userptr, "glTexCoord2sv"); + context->TexCoord3d = (PFNGLTEXCOORD3DPROC) load(userptr, "glTexCoord3d"); + context->TexCoord3dv = (PFNGLTEXCOORD3DVPROC) load(userptr, "glTexCoord3dv"); + context->TexCoord3f = (PFNGLTEXCOORD3FPROC) load(userptr, "glTexCoord3f"); + context->TexCoord3fv = (PFNGLTEXCOORD3FVPROC) load(userptr, "glTexCoord3fv"); + context->TexCoord3i = (PFNGLTEXCOORD3IPROC) load(userptr, "glTexCoord3i"); + context->TexCoord3iv = (PFNGLTEXCOORD3IVPROC) load(userptr, "glTexCoord3iv"); + context->TexCoord3s = (PFNGLTEXCOORD3SPROC) load(userptr, "glTexCoord3s"); + context->TexCoord3sv = (PFNGLTEXCOORD3SVPROC) load(userptr, "glTexCoord3sv"); + context->TexCoord4d = (PFNGLTEXCOORD4DPROC) load(userptr, "glTexCoord4d"); + context->TexCoord4dv = (PFNGLTEXCOORD4DVPROC) load(userptr, "glTexCoord4dv"); + context->TexCoord4f = (PFNGLTEXCOORD4FPROC) load(userptr, "glTexCoord4f"); + context->TexCoord4fv = (PFNGLTEXCOORD4FVPROC) load(userptr, "glTexCoord4fv"); + context->TexCoord4i = (PFNGLTEXCOORD4IPROC) load(userptr, "glTexCoord4i"); + context->TexCoord4iv = (PFNGLTEXCOORD4IVPROC) load(userptr, "glTexCoord4iv"); + context->TexCoord4s = (PFNGLTEXCOORD4SPROC) load(userptr, "glTexCoord4s"); + context->TexCoord4sv = (PFNGLTEXCOORD4SVPROC) load(userptr, "glTexCoord4sv"); + context->TexEnvf = (PFNGLTEXENVFPROC) load(userptr, "glTexEnvf"); + context->TexEnvfv = (PFNGLTEXENVFVPROC) load(userptr, "glTexEnvfv"); + context->TexEnvi = (PFNGLTEXENVIPROC) load(userptr, "glTexEnvi"); + context->TexEnviv = (PFNGLTEXENVIVPROC) load(userptr, "glTexEnviv"); + context->TexGend = (PFNGLTEXGENDPROC) load(userptr, "glTexGend"); + context->TexGendv = (PFNGLTEXGENDVPROC) load(userptr, "glTexGendv"); + context->TexGenf = (PFNGLTEXGENFPROC) load(userptr, "glTexGenf"); + context->TexGenfv = (PFNGLTEXGENFVPROC) load(userptr, "glTexGenfv"); + context->TexGeni = (PFNGLTEXGENIPROC) load(userptr, "glTexGeni"); + context->TexGeniv = (PFNGLTEXGENIVPROC) load(userptr, "glTexGeniv"); + context->TexImage1D = (PFNGLTEXIMAGE1DPROC) load(userptr, "glTexImage1D"); + context->TexImage2D = (PFNGLTEXIMAGE2DPROC) load(userptr, "glTexImage2D"); + context->TexParameterf = (PFNGLTEXPARAMETERFPROC) load(userptr, "glTexParameterf"); + context->TexParameterfv = (PFNGLTEXPARAMETERFVPROC) load(userptr, "glTexParameterfv"); + context->TexParameteri = (PFNGLTEXPARAMETERIPROC) load(userptr, "glTexParameteri"); + context->TexParameteriv = (PFNGLTEXPARAMETERIVPROC) load(userptr, "glTexParameteriv"); + context->Translated = (PFNGLTRANSLATEDPROC) load(userptr, "glTranslated"); + context->Translatef = (PFNGLTRANSLATEFPROC) load(userptr, "glTranslatef"); + context->Vertex2d = (PFNGLVERTEX2DPROC) load(userptr, "glVertex2d"); + context->Vertex2dv = (PFNGLVERTEX2DVPROC) load(userptr, "glVertex2dv"); + context->Vertex2f = (PFNGLVERTEX2FPROC) load(userptr, "glVertex2f"); + context->Vertex2fv = (PFNGLVERTEX2FVPROC) load(userptr, "glVertex2fv"); + context->Vertex2i = (PFNGLVERTEX2IPROC) load(userptr, "glVertex2i"); + context->Vertex2iv = (PFNGLVERTEX2IVPROC) load(userptr, "glVertex2iv"); + context->Vertex2s = (PFNGLVERTEX2SPROC) load(userptr, "glVertex2s"); + context->Vertex2sv = (PFNGLVERTEX2SVPROC) load(userptr, "glVertex2sv"); + context->Vertex3d = (PFNGLVERTEX3DPROC) load(userptr, "glVertex3d"); + context->Vertex3dv = (PFNGLVERTEX3DVPROC) load(userptr, "glVertex3dv"); + context->Vertex3f = (PFNGLVERTEX3FPROC) load(userptr, "glVertex3f"); + context->Vertex3fv = (PFNGLVERTEX3FVPROC) load(userptr, "glVertex3fv"); + context->Vertex3i = (PFNGLVERTEX3IPROC) load(userptr, "glVertex3i"); + context->Vertex3iv = (PFNGLVERTEX3IVPROC) load(userptr, "glVertex3iv"); + context->Vertex3s = (PFNGLVERTEX3SPROC) load(userptr, "glVertex3s"); + context->Vertex3sv = (PFNGLVERTEX3SVPROC) load(userptr, "glVertex3sv"); + context->Vertex4d = (PFNGLVERTEX4DPROC) load(userptr, "glVertex4d"); + context->Vertex4dv = (PFNGLVERTEX4DVPROC) load(userptr, "glVertex4dv"); + context->Vertex4f = (PFNGLVERTEX4FPROC) load(userptr, "glVertex4f"); + context->Vertex4fv = (PFNGLVERTEX4FVPROC) load(userptr, "glVertex4fv"); + context->Vertex4i = (PFNGLVERTEX4IPROC) load(userptr, "glVertex4i"); + context->Vertex4iv = (PFNGLVERTEX4IVPROC) load(userptr, "glVertex4iv"); + context->Vertex4s = (PFNGLVERTEX4SPROC) load(userptr, "glVertex4s"); + context->Vertex4sv = (PFNGLVERTEX4SVPROC) load(userptr, "glVertex4sv"); + context->Viewport = (PFNGLVIEWPORTPROC) load(userptr, "glViewport"); +} +static void glad_gl_load_GL_VERSION_1_1(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_1_1) return; + context->AreTexturesResident = (PFNGLARETEXTURESRESIDENTPROC) load(userptr, "glAreTexturesResident"); + context->ArrayElement = (PFNGLARRAYELEMENTPROC) load(userptr, "glArrayElement"); + context->BindTexture = (PFNGLBINDTEXTUREPROC) load(userptr, "glBindTexture"); + context->ColorPointer = (PFNGLCOLORPOINTERPROC) load(userptr, "glColorPointer"); + context->CopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC) load(userptr, "glCopyTexImage1D"); + context->CopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load(userptr, "glCopyTexImage2D"); + context->CopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC) load(userptr, "glCopyTexSubImage1D"); + context->CopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load(userptr, "glCopyTexSubImage2D"); + context->DeleteTextures = (PFNGLDELETETEXTURESPROC) load(userptr, "glDeleteTextures"); + context->DisableClientState = (PFNGLDISABLECLIENTSTATEPROC) load(userptr, "glDisableClientState"); + context->DrawArrays = (PFNGLDRAWARRAYSPROC) load(userptr, "glDrawArrays"); + context->DrawElements = (PFNGLDRAWELEMENTSPROC) load(userptr, "glDrawElements"); + context->EdgeFlagPointer = (PFNGLEDGEFLAGPOINTERPROC) load(userptr, "glEdgeFlagPointer"); + context->EnableClientState = (PFNGLENABLECLIENTSTATEPROC) load(userptr, "glEnableClientState"); + context->GenTextures = (PFNGLGENTEXTURESPROC) load(userptr, "glGenTextures"); + context->GetPointerv = (PFNGLGETPOINTERVPROC) load(userptr, "glGetPointerv"); + context->IndexPointer = (PFNGLINDEXPOINTERPROC) load(userptr, "glIndexPointer"); + context->Indexub = (PFNGLINDEXUBPROC) load(userptr, "glIndexub"); + context->Indexubv = (PFNGLINDEXUBVPROC) load(userptr, "glIndexubv"); + context->InterleavedArrays = (PFNGLINTERLEAVEDARRAYSPROC) load(userptr, "glInterleavedArrays"); + context->IsTexture = (PFNGLISTEXTUREPROC) load(userptr, "glIsTexture"); + context->NormalPointer = (PFNGLNORMALPOINTERPROC) load(userptr, "glNormalPointer"); + context->PolygonOffset = (PFNGLPOLYGONOFFSETPROC) load(userptr, "glPolygonOffset"); + context->PopClientAttrib = (PFNGLPOPCLIENTATTRIBPROC) load(userptr, "glPopClientAttrib"); + context->PrioritizeTextures = (PFNGLPRIORITIZETEXTURESPROC) load(userptr, "glPrioritizeTextures"); + context->PushClientAttrib = (PFNGLPUSHCLIENTATTRIBPROC) load(userptr, "glPushClientAttrib"); + context->TexCoordPointer = (PFNGLTEXCOORDPOINTERPROC) load(userptr, "glTexCoordPointer"); + context->TexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC) load(userptr, "glTexSubImage1D"); + context->TexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load(userptr, "glTexSubImage2D"); + context->VertexPointer = (PFNGLVERTEXPOINTERPROC) load(userptr, "glVertexPointer"); +} +static void glad_gl_load_GL_VERSION_1_2(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_1_2) return; + context->CopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) load(userptr, "glCopyTexSubImage3D"); + context->DrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) load(userptr, "glDrawRangeElements"); + context->TexImage3D = (PFNGLTEXIMAGE3DPROC) load(userptr, "glTexImage3D"); + context->TexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) load(userptr, "glTexSubImage3D"); +} +static void glad_gl_load_GL_VERSION_1_3(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_1_3) return; + context->ActiveTexture = (PFNGLACTIVETEXTUREPROC) load(userptr, "glActiveTexture"); + context->ClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC) load(userptr, "glClientActiveTexture"); + context->CompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC) load(userptr, "glCompressedTexImage1D"); + context->CompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load(userptr, "glCompressedTexImage2D"); + context->CompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) load(userptr, "glCompressedTexImage3D"); + context->CompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) load(userptr, "glCompressedTexSubImage1D"); + context->CompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load(userptr, "glCompressedTexSubImage2D"); + context->CompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) load(userptr, "glCompressedTexSubImage3D"); + context->GetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC) load(userptr, "glGetCompressedTexImage"); + context->LoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC) load(userptr, "glLoadTransposeMatrixd"); + context->LoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC) load(userptr, "glLoadTransposeMatrixf"); + context->MultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC) load(userptr, "glMultTransposeMatrixd"); + context->MultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC) load(userptr, "glMultTransposeMatrixf"); + context->MultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC) load(userptr, "glMultiTexCoord1d"); + context->MultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC) load(userptr, "glMultiTexCoord1dv"); + context->MultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC) load(userptr, "glMultiTexCoord1f"); + context->MultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC) load(userptr, "glMultiTexCoord1fv"); + context->MultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC) load(userptr, "glMultiTexCoord1i"); + context->MultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC) load(userptr, "glMultiTexCoord1iv"); + context->MultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC) load(userptr, "glMultiTexCoord1s"); + context->MultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC) load(userptr, "glMultiTexCoord1sv"); + context->MultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC) load(userptr, "glMultiTexCoord2d"); + context->MultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC) load(userptr, "glMultiTexCoord2dv"); + context->MultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC) load(userptr, "glMultiTexCoord2f"); + context->MultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC) load(userptr, "glMultiTexCoord2fv"); + context->MultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC) load(userptr, "glMultiTexCoord2i"); + context->MultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC) load(userptr, "glMultiTexCoord2iv"); + context->MultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC) load(userptr, "glMultiTexCoord2s"); + context->MultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC) load(userptr, "glMultiTexCoord2sv"); + context->MultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC) load(userptr, "glMultiTexCoord3d"); + context->MultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC) load(userptr, "glMultiTexCoord3dv"); + context->MultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC) load(userptr, "glMultiTexCoord3f"); + context->MultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC) load(userptr, "glMultiTexCoord3fv"); + context->MultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC) load(userptr, "glMultiTexCoord3i"); + context->MultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC) load(userptr, "glMultiTexCoord3iv"); + context->MultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC) load(userptr, "glMultiTexCoord3s"); + context->MultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC) load(userptr, "glMultiTexCoord3sv"); + context->MultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC) load(userptr, "glMultiTexCoord4d"); + context->MultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC) load(userptr, "glMultiTexCoord4dv"); + context->MultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC) load(userptr, "glMultiTexCoord4f"); + context->MultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC) load(userptr, "glMultiTexCoord4fv"); + context->MultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC) load(userptr, "glMultiTexCoord4i"); + context->MultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC) load(userptr, "glMultiTexCoord4iv"); + context->MultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC) load(userptr, "glMultiTexCoord4s"); + context->MultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC) load(userptr, "glMultiTexCoord4sv"); + context->SampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load(userptr, "glSampleCoverage"); +} +static void glad_gl_load_GL_VERSION_1_4(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_1_4) return; + context->BlendColor = (PFNGLBLENDCOLORPROC) load(userptr, "glBlendColor"); + context->BlendEquation = (PFNGLBLENDEQUATIONPROC) load(userptr, "glBlendEquation"); + context->BlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load(userptr, "glBlendFuncSeparate"); + context->FogCoordPointer = (PFNGLFOGCOORDPOINTERPROC) load(userptr, "glFogCoordPointer"); + context->FogCoordd = (PFNGLFOGCOORDDPROC) load(userptr, "glFogCoordd"); + context->FogCoorddv = (PFNGLFOGCOORDDVPROC) load(userptr, "glFogCoorddv"); + context->FogCoordf = (PFNGLFOGCOORDFPROC) load(userptr, "glFogCoordf"); + context->FogCoordfv = (PFNGLFOGCOORDFVPROC) load(userptr, "glFogCoordfv"); + context->MultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC) load(userptr, "glMultiDrawArrays"); + context->MultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC) load(userptr, "glMultiDrawElements"); + context->PointParameterf = (PFNGLPOINTPARAMETERFPROC) load(userptr, "glPointParameterf"); + context->PointParameterfv = (PFNGLPOINTPARAMETERFVPROC) load(userptr, "glPointParameterfv"); + context->PointParameteri = (PFNGLPOINTPARAMETERIPROC) load(userptr, "glPointParameteri"); + context->PointParameteriv = (PFNGLPOINTPARAMETERIVPROC) load(userptr, "glPointParameteriv"); + context->SecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC) load(userptr, "glSecondaryColor3b"); + context->SecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC) load(userptr, "glSecondaryColor3bv"); + context->SecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC) load(userptr, "glSecondaryColor3d"); + context->SecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC) load(userptr, "glSecondaryColor3dv"); + context->SecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC) load(userptr, "glSecondaryColor3f"); + context->SecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC) load(userptr, "glSecondaryColor3fv"); + context->SecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC) load(userptr, "glSecondaryColor3i"); + context->SecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC) load(userptr, "glSecondaryColor3iv"); + context->SecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC) load(userptr, "glSecondaryColor3s"); + context->SecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC) load(userptr, "glSecondaryColor3sv"); + context->SecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC) load(userptr, "glSecondaryColor3ub"); + context->SecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC) load(userptr, "glSecondaryColor3ubv"); + context->SecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC) load(userptr, "glSecondaryColor3ui"); + context->SecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC) load(userptr, "glSecondaryColor3uiv"); + context->SecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC) load(userptr, "glSecondaryColor3us"); + context->SecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC) load(userptr, "glSecondaryColor3usv"); + context->SecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC) load(userptr, "glSecondaryColorPointer"); + context->WindowPos2d = (PFNGLWINDOWPOS2DPROC) load(userptr, "glWindowPos2d"); + context->WindowPos2dv = (PFNGLWINDOWPOS2DVPROC) load(userptr, "glWindowPos2dv"); + context->WindowPos2f = (PFNGLWINDOWPOS2FPROC) load(userptr, "glWindowPos2f"); + context->WindowPos2fv = (PFNGLWINDOWPOS2FVPROC) load(userptr, "glWindowPos2fv"); + context->WindowPos2i = (PFNGLWINDOWPOS2IPROC) load(userptr, "glWindowPos2i"); + context->WindowPos2iv = (PFNGLWINDOWPOS2IVPROC) load(userptr, "glWindowPos2iv"); + context->WindowPos2s = (PFNGLWINDOWPOS2SPROC) load(userptr, "glWindowPos2s"); + context->WindowPos2sv = (PFNGLWINDOWPOS2SVPROC) load(userptr, "glWindowPos2sv"); + context->WindowPos3d = (PFNGLWINDOWPOS3DPROC) load(userptr, "glWindowPos3d"); + context->WindowPos3dv = (PFNGLWINDOWPOS3DVPROC) load(userptr, "glWindowPos3dv"); + context->WindowPos3f = (PFNGLWINDOWPOS3FPROC) load(userptr, "glWindowPos3f"); + context->WindowPos3fv = (PFNGLWINDOWPOS3FVPROC) load(userptr, "glWindowPos3fv"); + context->WindowPos3i = (PFNGLWINDOWPOS3IPROC) load(userptr, "glWindowPos3i"); + context->WindowPos3iv = (PFNGLWINDOWPOS3IVPROC) load(userptr, "glWindowPos3iv"); + context->WindowPos3s = (PFNGLWINDOWPOS3SPROC) load(userptr, "glWindowPos3s"); + context->WindowPos3sv = (PFNGLWINDOWPOS3SVPROC) load(userptr, "glWindowPos3sv"); +} +static void glad_gl_load_GL_VERSION_1_5(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_1_5) return; + context->BeginQuery = (PFNGLBEGINQUERYPROC) load(userptr, "glBeginQuery"); + context->BindBuffer = (PFNGLBINDBUFFERPROC) load(userptr, "glBindBuffer"); + context->BufferData = (PFNGLBUFFERDATAPROC) load(userptr, "glBufferData"); + context->BufferSubData = (PFNGLBUFFERSUBDATAPROC) load(userptr, "glBufferSubData"); + context->DeleteBuffers = (PFNGLDELETEBUFFERSPROC) load(userptr, "glDeleteBuffers"); + context->DeleteQueries = (PFNGLDELETEQUERIESPROC) load(userptr, "glDeleteQueries"); + context->EndQuery = (PFNGLENDQUERYPROC) load(userptr, "glEndQuery"); + context->GenBuffers = (PFNGLGENBUFFERSPROC) load(userptr, "glGenBuffers"); + context->GenQueries = (PFNGLGENQUERIESPROC) load(userptr, "glGenQueries"); + context->GetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load(userptr, "glGetBufferParameteriv"); + context->GetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) load(userptr, "glGetBufferPointerv"); + context->GetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC) load(userptr, "glGetBufferSubData"); + context->GetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC) load(userptr, "glGetQueryObjectiv"); + context->GetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) load(userptr, "glGetQueryObjectuiv"); + context->GetQueryiv = (PFNGLGETQUERYIVPROC) load(userptr, "glGetQueryiv"); + context->IsBuffer = (PFNGLISBUFFERPROC) load(userptr, "glIsBuffer"); + context->IsQuery = (PFNGLISQUERYPROC) load(userptr, "glIsQuery"); + context->MapBuffer = (PFNGLMAPBUFFERPROC) load(userptr, "glMapBuffer"); + context->UnmapBuffer = (PFNGLUNMAPBUFFERPROC) load(userptr, "glUnmapBuffer"); +} +static void glad_gl_load_GL_VERSION_2_0(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_2_0) return; + context->AttachShader = (PFNGLATTACHSHADERPROC) load(userptr, "glAttachShader"); + context->BindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load(userptr, "glBindAttribLocation"); + context->BlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load(userptr, "glBlendEquationSeparate"); + context->CompileShader = (PFNGLCOMPILESHADERPROC) load(userptr, "glCompileShader"); + context->CreateProgram = (PFNGLCREATEPROGRAMPROC) load(userptr, "glCreateProgram"); + context->CreateShader = (PFNGLCREATESHADERPROC) load(userptr, "glCreateShader"); + context->DeleteProgram = (PFNGLDELETEPROGRAMPROC) load(userptr, "glDeleteProgram"); + context->DeleteShader = (PFNGLDELETESHADERPROC) load(userptr, "glDeleteShader"); + context->DetachShader = (PFNGLDETACHSHADERPROC) load(userptr, "glDetachShader"); + context->DisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load(userptr, "glDisableVertexAttribArray"); + context->DrawBuffers = (PFNGLDRAWBUFFERSPROC) load(userptr, "glDrawBuffers"); + context->EnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load(userptr, "glEnableVertexAttribArray"); + context->GetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load(userptr, "glGetActiveAttrib"); + context->GetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load(userptr, "glGetActiveUniform"); + context->GetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load(userptr, "glGetAttachedShaders"); + context->GetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load(userptr, "glGetAttribLocation"); + context->GetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load(userptr, "glGetProgramInfoLog"); + context->GetProgramiv = (PFNGLGETPROGRAMIVPROC) load(userptr, "glGetProgramiv"); + context->GetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load(userptr, "glGetShaderInfoLog"); + context->GetShaderSource = (PFNGLGETSHADERSOURCEPROC) load(userptr, "glGetShaderSource"); + context->GetShaderiv = (PFNGLGETSHADERIVPROC) load(userptr, "glGetShaderiv"); + context->GetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load(userptr, "glGetUniformLocation"); + context->GetUniformfv = (PFNGLGETUNIFORMFVPROC) load(userptr, "glGetUniformfv"); + context->GetUniformiv = (PFNGLGETUNIFORMIVPROC) load(userptr, "glGetUniformiv"); + context->GetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load(userptr, "glGetVertexAttribPointerv"); + context->GetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC) load(userptr, "glGetVertexAttribdv"); + context->GetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load(userptr, "glGetVertexAttribfv"); + context->GetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load(userptr, "glGetVertexAttribiv"); + context->IsProgram = (PFNGLISPROGRAMPROC) load(userptr, "glIsProgram"); + context->IsShader = (PFNGLISSHADERPROC) load(userptr, "glIsShader"); + context->LinkProgram = (PFNGLLINKPROGRAMPROC) load(userptr, "glLinkProgram"); + context->ShaderSource = (PFNGLSHADERSOURCEPROC) load(userptr, "glShaderSource"); + context->StencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load(userptr, "glStencilFuncSeparate"); + context->StencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load(userptr, "glStencilMaskSeparate"); + context->StencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load(userptr, "glStencilOpSeparate"); + context->Uniform1f = (PFNGLUNIFORM1FPROC) load(userptr, "glUniform1f"); + context->Uniform1fv = (PFNGLUNIFORM1FVPROC) load(userptr, "glUniform1fv"); + context->Uniform1i = (PFNGLUNIFORM1IPROC) load(userptr, "glUniform1i"); + context->Uniform1iv = (PFNGLUNIFORM1IVPROC) load(userptr, "glUniform1iv"); + context->Uniform2f = (PFNGLUNIFORM2FPROC) load(userptr, "glUniform2f"); + context->Uniform2fv = (PFNGLUNIFORM2FVPROC) load(userptr, "glUniform2fv"); + context->Uniform2i = (PFNGLUNIFORM2IPROC) load(userptr, "glUniform2i"); + context->Uniform2iv = (PFNGLUNIFORM2IVPROC) load(userptr, "glUniform2iv"); + context->Uniform3f = (PFNGLUNIFORM3FPROC) load(userptr, "glUniform3f"); + context->Uniform3fv = (PFNGLUNIFORM3FVPROC) load(userptr, "glUniform3fv"); + context->Uniform3i = (PFNGLUNIFORM3IPROC) load(userptr, "glUniform3i"); + context->Uniform3iv = (PFNGLUNIFORM3IVPROC) load(userptr, "glUniform3iv"); + context->Uniform4f = (PFNGLUNIFORM4FPROC) load(userptr, "glUniform4f"); + context->Uniform4fv = (PFNGLUNIFORM4FVPROC) load(userptr, "glUniform4fv"); + context->Uniform4i = (PFNGLUNIFORM4IPROC) load(userptr, "glUniform4i"); + context->Uniform4iv = (PFNGLUNIFORM4IVPROC) load(userptr, "glUniform4iv"); + context->UniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load(userptr, "glUniformMatrix2fv"); + context->UniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load(userptr, "glUniformMatrix3fv"); + context->UniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load(userptr, "glUniformMatrix4fv"); + context->UseProgram = (PFNGLUSEPROGRAMPROC) load(userptr, "glUseProgram"); + context->ValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load(userptr, "glValidateProgram"); + context->VertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC) load(userptr, "glVertexAttrib1d"); + context->VertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC) load(userptr, "glVertexAttrib1dv"); + context->VertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load(userptr, "glVertexAttrib1f"); + context->VertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load(userptr, "glVertexAttrib1fv"); + context->VertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC) load(userptr, "glVertexAttrib1s"); + context->VertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC) load(userptr, "glVertexAttrib1sv"); + context->VertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC) load(userptr, "glVertexAttrib2d"); + context->VertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC) load(userptr, "glVertexAttrib2dv"); + context->VertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load(userptr, "glVertexAttrib2f"); + context->VertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load(userptr, "glVertexAttrib2fv"); + context->VertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC) load(userptr, "glVertexAttrib2s"); + context->VertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC) load(userptr, "glVertexAttrib2sv"); + context->VertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC) load(userptr, "glVertexAttrib3d"); + context->VertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC) load(userptr, "glVertexAttrib3dv"); + context->VertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load(userptr, "glVertexAttrib3f"); + context->VertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load(userptr, "glVertexAttrib3fv"); + context->VertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC) load(userptr, "glVertexAttrib3s"); + context->VertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC) load(userptr, "glVertexAttrib3sv"); + context->VertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC) load(userptr, "glVertexAttrib4Nbv"); + context->VertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC) load(userptr, "glVertexAttrib4Niv"); + context->VertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC) load(userptr, "glVertexAttrib4Nsv"); + context->VertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC) load(userptr, "glVertexAttrib4Nub"); + context->VertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC) load(userptr, "glVertexAttrib4Nubv"); + context->VertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC) load(userptr, "glVertexAttrib4Nuiv"); + context->VertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC) load(userptr, "glVertexAttrib4Nusv"); + context->VertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC) load(userptr, "glVertexAttrib4bv"); + context->VertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC) load(userptr, "glVertexAttrib4d"); + context->VertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC) load(userptr, "glVertexAttrib4dv"); + context->VertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load(userptr, "glVertexAttrib4f"); + context->VertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load(userptr, "glVertexAttrib4fv"); + context->VertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC) load(userptr, "glVertexAttrib4iv"); + context->VertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC) load(userptr, "glVertexAttrib4s"); + context->VertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC) load(userptr, "glVertexAttrib4sv"); + context->VertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC) load(userptr, "glVertexAttrib4ubv"); + context->VertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC) load(userptr, "glVertexAttrib4uiv"); + context->VertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC) load(userptr, "glVertexAttrib4usv"); + context->VertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load(userptr, "glVertexAttribPointer"); +} +static void glad_gl_load_GL_VERSION_2_1(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_2_1) return; + context->UniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) load(userptr, "glUniformMatrix2x3fv"); + context->UniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) load(userptr, "glUniformMatrix2x4fv"); + context->UniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) load(userptr, "glUniformMatrix3x2fv"); + context->UniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) load(userptr, "glUniformMatrix3x4fv"); + context->UniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) load(userptr, "glUniformMatrix4x2fv"); + context->UniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) load(userptr, "glUniformMatrix4x3fv"); +} +static void glad_gl_load_GL_VERSION_3_0(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_3_0) return; + context->BeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC) load(userptr, "glBeginConditionalRender"); + context->BeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) load(userptr, "glBeginTransformFeedback"); + context->BindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); + context->BindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); + context->BindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC) load(userptr, "glBindFragDataLocation"); + context->BindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load(userptr, "glBindFramebuffer"); + context->BindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load(userptr, "glBindRenderbuffer"); + context->BindVertexArray = (PFNGLBINDVERTEXARRAYPROC) load(userptr, "glBindVertexArray"); + context->BlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load(userptr, "glBlitFramebuffer"); + context->CheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckFramebufferStatus"); + context->ClampColor = (PFNGLCLAMPCOLORPROC) load(userptr, "glClampColor"); + context->ClearBufferfi = (PFNGLCLEARBUFFERFIPROC) load(userptr, "glClearBufferfi"); + context->ClearBufferfv = (PFNGLCLEARBUFFERFVPROC) load(userptr, "glClearBufferfv"); + context->ClearBufferiv = (PFNGLCLEARBUFFERIVPROC) load(userptr, "glClearBufferiv"); + context->ClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) load(userptr, "glClearBufferuiv"); + context->ColorMaski = (PFNGLCOLORMASKIPROC) load(userptr, "glColorMaski"); + context->DeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load(userptr, "glDeleteFramebuffers"); + context->DeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load(userptr, "glDeleteRenderbuffers"); + context->DeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) load(userptr, "glDeleteVertexArrays"); + context->Disablei = (PFNGLDISABLEIPROC) load(userptr, "glDisablei"); + context->Enablei = (PFNGLENABLEIPROC) load(userptr, "glEnablei"); + context->EndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC) load(userptr, "glEndConditionalRender"); + context->EndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) load(userptr, "glEndTransformFeedback"); + context->FlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load(userptr, "glFlushMappedBufferRange"); + context->FramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glFramebufferRenderbuffer"); + context->FramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) load(userptr, "glFramebufferTexture1D"); + context->FramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load(userptr, "glFramebufferTexture2D"); + context->FramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) load(userptr, "glFramebufferTexture3D"); + context->FramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glFramebufferTextureLayer"); + context->GenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load(userptr, "glGenFramebuffers"); + context->GenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load(userptr, "glGenRenderbuffers"); + context->GenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) load(userptr, "glGenVertexArrays"); + context->GenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load(userptr, "glGenerateMipmap"); + context->GetBooleani_v = (PFNGLGETBOOLEANI_VPROC) load(userptr, "glGetBooleani_v"); + context->GetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) load(userptr, "glGetFragDataLocation"); + context->GetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetFramebufferAttachmentParameteriv"); + context->GetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); + context->GetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetRenderbufferParameteriv"); + context->GetStringi = (PFNGLGETSTRINGIPROC) load(userptr, "glGetStringi"); + context->GetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC) load(userptr, "glGetTexParameterIiv"); + context->GetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC) load(userptr, "glGetTexParameterIuiv"); + context->GetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) load(userptr, "glGetTransformFeedbackVarying"); + context->GetUniformuiv = (PFNGLGETUNIFORMUIVPROC) load(userptr, "glGetUniformuiv"); + context->GetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) load(userptr, "glGetVertexAttribIiv"); + context->GetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) load(userptr, "glGetVertexAttribIuiv"); + context->IsEnabledi = (PFNGLISENABLEDIPROC) load(userptr, "glIsEnabledi"); + context->IsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load(userptr, "glIsFramebuffer"); + context->IsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load(userptr, "glIsRenderbuffer"); + context->IsVertexArray = (PFNGLISVERTEXARRAYPROC) load(userptr, "glIsVertexArray"); + context->MapBufferRange = (PFNGLMAPBUFFERRANGEPROC) load(userptr, "glMapBufferRange"); + context->RenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load(userptr, "glRenderbufferStorage"); + context->RenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glRenderbufferStorageMultisample"); + context->TexParameterIiv = (PFNGLTEXPARAMETERIIVPROC) load(userptr, "glTexParameterIiv"); + context->TexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC) load(userptr, "glTexParameterIuiv"); + context->TransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) load(userptr, "glTransformFeedbackVaryings"); + context->Uniform1ui = (PFNGLUNIFORM1UIPROC) load(userptr, "glUniform1ui"); + context->Uniform1uiv = (PFNGLUNIFORM1UIVPROC) load(userptr, "glUniform1uiv"); + context->Uniform2ui = (PFNGLUNIFORM2UIPROC) load(userptr, "glUniform2ui"); + context->Uniform2uiv = (PFNGLUNIFORM2UIVPROC) load(userptr, "glUniform2uiv"); + context->Uniform3ui = (PFNGLUNIFORM3UIPROC) load(userptr, "glUniform3ui"); + context->Uniform3uiv = (PFNGLUNIFORM3UIVPROC) load(userptr, "glUniform3uiv"); + context->Uniform4ui = (PFNGLUNIFORM4UIPROC) load(userptr, "glUniform4ui"); + context->Uniform4uiv = (PFNGLUNIFORM4UIVPROC) load(userptr, "glUniform4uiv"); + context->VertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC) load(userptr, "glVertexAttribI1i"); + context->VertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC) load(userptr, "glVertexAttribI1iv"); + context->VertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC) load(userptr, "glVertexAttribI1ui"); + context->VertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC) load(userptr, "glVertexAttribI1uiv"); + context->VertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC) load(userptr, "glVertexAttribI2i"); + context->VertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC) load(userptr, "glVertexAttribI2iv"); + context->VertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC) load(userptr, "glVertexAttribI2ui"); + context->VertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC) load(userptr, "glVertexAttribI2uiv"); + context->VertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC) load(userptr, "glVertexAttribI3i"); + context->VertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC) load(userptr, "glVertexAttribI3iv"); + context->VertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC) load(userptr, "glVertexAttribI3ui"); + context->VertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC) load(userptr, "glVertexAttribI3uiv"); + context->VertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC) load(userptr, "glVertexAttribI4bv"); + context->VertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) load(userptr, "glVertexAttribI4i"); + context->VertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) load(userptr, "glVertexAttribI4iv"); + context->VertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC) load(userptr, "glVertexAttribI4sv"); + context->VertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC) load(userptr, "glVertexAttribI4ubv"); + context->VertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) load(userptr, "glVertexAttribI4ui"); + context->VertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) load(userptr, "glVertexAttribI4uiv"); + context->VertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC) load(userptr, "glVertexAttribI4usv"); + context->VertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) load(userptr, "glVertexAttribIPointer"); +} +static void glad_gl_load_GL_VERSION_3_1(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_3_1) return; + context->BindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); + context->BindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); + context->CopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) load(userptr, "glCopyBufferSubData"); + context->DrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) load(userptr, "glDrawArraysInstanced"); + context->DrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) load(userptr, "glDrawElementsInstanced"); + context->GetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) load(userptr, "glGetActiveUniformBlockName"); + context->GetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) load(userptr, "glGetActiveUniformBlockiv"); + context->GetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC) load(userptr, "glGetActiveUniformName"); + context->GetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) load(userptr, "glGetActiveUniformsiv"); + context->GetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); + context->GetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) load(userptr, "glGetUniformBlockIndex"); + context->GetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) load(userptr, "glGetUniformIndices"); + context->PrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC) load(userptr, "glPrimitiveRestartIndex"); + context->TexBuffer = (PFNGLTEXBUFFERPROC) load(userptr, "glTexBuffer"); + context->UniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) load(userptr, "glUniformBlockBinding"); +} +static void glad_gl_load_GL_VERSION_3_2(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_3_2) return; + context->ClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) load(userptr, "glClientWaitSync"); + context->DeleteSync = (PFNGLDELETESYNCPROC) load(userptr, "glDeleteSync"); + context->DrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glDrawElementsBaseVertex"); + context->DrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) load(userptr, "glDrawElementsInstancedBaseVertex"); + context->DrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) load(userptr, "glDrawRangeElementsBaseVertex"); + context->FenceSync = (PFNGLFENCESYNCPROC) load(userptr, "glFenceSync"); + context->FramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC) load(userptr, "glFramebufferTexture"); + context->GetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) load(userptr, "glGetBufferParameteri64v"); + context->GetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) load(userptr, "glGetInteger64i_v"); + context->GetInteger64v = (PFNGLGETINTEGER64VPROC) load(userptr, "glGetInteger64v"); + context->GetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) load(userptr, "glGetMultisamplefv"); + context->GetSynciv = (PFNGLGETSYNCIVPROC) load(userptr, "glGetSynciv"); + context->IsSync = (PFNGLISSYNCPROC) load(userptr, "glIsSync"); + context->MultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) load(userptr, "glMultiDrawElementsBaseVertex"); + context->ProvokingVertex = (PFNGLPROVOKINGVERTEXPROC) load(userptr, "glProvokingVertex"); + context->SampleMaski = (PFNGLSAMPLEMASKIPROC) load(userptr, "glSampleMaski"); + context->TexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) load(userptr, "glTexImage2DMultisample"); + context->TexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) load(userptr, "glTexImage3DMultisample"); + context->WaitSync = (PFNGLWAITSYNCPROC) load(userptr, "glWaitSync"); +} +static void glad_gl_load_GL_VERSION_3_3(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_3_3) return; + context->BindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) load(userptr, "glBindFragDataLocationIndexed"); + context->BindSampler = (PFNGLBINDSAMPLERPROC) load(userptr, "glBindSampler"); + context->ColorP3ui = (PFNGLCOLORP3UIPROC) load(userptr, "glColorP3ui"); + context->ColorP3uiv = (PFNGLCOLORP3UIVPROC) load(userptr, "glColorP3uiv"); + context->ColorP4ui = (PFNGLCOLORP4UIPROC) load(userptr, "glColorP4ui"); + context->ColorP4uiv = (PFNGLCOLORP4UIVPROC) load(userptr, "glColorP4uiv"); + context->DeleteSamplers = (PFNGLDELETESAMPLERSPROC) load(userptr, "glDeleteSamplers"); + context->GenSamplers = (PFNGLGENSAMPLERSPROC) load(userptr, "glGenSamplers"); + context->GetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC) load(userptr, "glGetFragDataIndex"); + context->GetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) load(userptr, "glGetQueryObjecti64v"); + context->GetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) load(userptr, "glGetQueryObjectui64v"); + context->GetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC) load(userptr, "glGetSamplerParameterIiv"); + context->GetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC) load(userptr, "glGetSamplerParameterIuiv"); + context->GetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) load(userptr, "glGetSamplerParameterfv"); + context->GetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) load(userptr, "glGetSamplerParameteriv"); + context->IsSampler = (PFNGLISSAMPLERPROC) load(userptr, "glIsSampler"); + context->MultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC) load(userptr, "glMultiTexCoordP1ui"); + context->MultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC) load(userptr, "glMultiTexCoordP1uiv"); + context->MultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC) load(userptr, "glMultiTexCoordP2ui"); + context->MultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC) load(userptr, "glMultiTexCoordP2uiv"); + context->MultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC) load(userptr, "glMultiTexCoordP3ui"); + context->MultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC) load(userptr, "glMultiTexCoordP3uiv"); + context->MultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC) load(userptr, "glMultiTexCoordP4ui"); + context->MultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC) load(userptr, "glMultiTexCoordP4uiv"); + context->NormalP3ui = (PFNGLNORMALP3UIPROC) load(userptr, "glNormalP3ui"); + context->NormalP3uiv = (PFNGLNORMALP3UIVPROC) load(userptr, "glNormalP3uiv"); + context->QueryCounter = (PFNGLQUERYCOUNTERPROC) load(userptr, "glQueryCounter"); + context->SamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC) load(userptr, "glSamplerParameterIiv"); + context->SamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC) load(userptr, "glSamplerParameterIuiv"); + context->SamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) load(userptr, "glSamplerParameterf"); + context->SamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) load(userptr, "glSamplerParameterfv"); + context->SamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) load(userptr, "glSamplerParameteri"); + context->SamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) load(userptr, "glSamplerParameteriv"); + context->SecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC) load(userptr, "glSecondaryColorP3ui"); + context->SecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC) load(userptr, "glSecondaryColorP3uiv"); + context->TexCoordP1ui = (PFNGLTEXCOORDP1UIPROC) load(userptr, "glTexCoordP1ui"); + context->TexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC) load(userptr, "glTexCoordP1uiv"); + context->TexCoordP2ui = (PFNGLTEXCOORDP2UIPROC) load(userptr, "glTexCoordP2ui"); + context->TexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC) load(userptr, "glTexCoordP2uiv"); + context->TexCoordP3ui = (PFNGLTEXCOORDP3UIPROC) load(userptr, "glTexCoordP3ui"); + context->TexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC) load(userptr, "glTexCoordP3uiv"); + context->TexCoordP4ui = (PFNGLTEXCOORDP4UIPROC) load(userptr, "glTexCoordP4ui"); + context->TexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC) load(userptr, "glTexCoordP4uiv"); + context->VertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) load(userptr, "glVertexAttribDivisor"); + context->VertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC) load(userptr, "glVertexAttribP1ui"); + context->VertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC) load(userptr, "glVertexAttribP1uiv"); + context->VertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC) load(userptr, "glVertexAttribP2ui"); + context->VertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC) load(userptr, "glVertexAttribP2uiv"); + context->VertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC) load(userptr, "glVertexAttribP3ui"); + context->VertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC) load(userptr, "glVertexAttribP3uiv"); + context->VertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC) load(userptr, "glVertexAttribP4ui"); + context->VertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC) load(userptr, "glVertexAttribP4uiv"); + context->VertexP2ui = (PFNGLVERTEXP2UIPROC) load(userptr, "glVertexP2ui"); + context->VertexP2uiv = (PFNGLVERTEXP2UIVPROC) load(userptr, "glVertexP2uiv"); + context->VertexP3ui = (PFNGLVERTEXP3UIPROC) load(userptr, "glVertexP3ui"); + context->VertexP3uiv = (PFNGLVERTEXP3UIVPROC) load(userptr, "glVertexP3uiv"); + context->VertexP4ui = (PFNGLVERTEXP4UIPROC) load(userptr, "glVertexP4ui"); + context->VertexP4uiv = (PFNGLVERTEXP4UIVPROC) load(userptr, "glVertexP4uiv"); +} +static void glad_gl_load_GL_VERSION_4_0(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_4_0) return; + context->BeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC) load(userptr, "glBeginQueryIndexed"); + context->BindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC) load(userptr, "glBindTransformFeedback"); + context->BlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC) load(userptr, "glBlendEquationSeparatei"); + context->BlendEquationi = (PFNGLBLENDEQUATIONIPROC) load(userptr, "glBlendEquationi"); + context->BlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC) load(userptr, "glBlendFuncSeparatei"); + context->BlendFunci = (PFNGLBLENDFUNCIPROC) load(userptr, "glBlendFunci"); + context->DeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC) load(userptr, "glDeleteTransformFeedbacks"); + context->DrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC) load(userptr, "glDrawArraysIndirect"); + context->DrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC) load(userptr, "glDrawElementsIndirect"); + context->DrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC) load(userptr, "glDrawTransformFeedback"); + context->DrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) load(userptr, "glDrawTransformFeedbackStream"); + context->EndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC) load(userptr, "glEndQueryIndexed"); + context->GenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC) load(userptr, "glGenTransformFeedbacks"); + context->GetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC) load(userptr, "glGetActiveSubroutineName"); + context->GetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) load(userptr, "glGetActiveSubroutineUniformName"); + context->GetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) load(userptr, "glGetActiveSubroutineUniformiv"); + context->GetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC) load(userptr, "glGetProgramStageiv"); + context->GetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC) load(userptr, "glGetQueryIndexediv"); + context->GetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC) load(userptr, "glGetSubroutineIndex"); + context->GetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) load(userptr, "glGetSubroutineUniformLocation"); + context->GetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC) load(userptr, "glGetUniformSubroutineuiv"); + context->GetUniformdv = (PFNGLGETUNIFORMDVPROC) load(userptr, "glGetUniformdv"); + context->IsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC) load(userptr, "glIsTransformFeedback"); + context->MinSampleShading = (PFNGLMINSAMPLESHADINGPROC) load(userptr, "glMinSampleShading"); + context->PatchParameterfv = (PFNGLPATCHPARAMETERFVPROC) load(userptr, "glPatchParameterfv"); + context->PatchParameteri = (PFNGLPATCHPARAMETERIPROC) load(userptr, "glPatchParameteri"); + context->PauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC) load(userptr, "glPauseTransformFeedback"); + context->ResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC) load(userptr, "glResumeTransformFeedback"); + context->Uniform1d = (PFNGLUNIFORM1DPROC) load(userptr, "glUniform1d"); + context->Uniform1dv = (PFNGLUNIFORM1DVPROC) load(userptr, "glUniform1dv"); + context->Uniform2d = (PFNGLUNIFORM2DPROC) load(userptr, "glUniform2d"); + context->Uniform2dv = (PFNGLUNIFORM2DVPROC) load(userptr, "glUniform2dv"); + context->Uniform3d = (PFNGLUNIFORM3DPROC) load(userptr, "glUniform3d"); + context->Uniform3dv = (PFNGLUNIFORM3DVPROC) load(userptr, "glUniform3dv"); + context->Uniform4d = (PFNGLUNIFORM4DPROC) load(userptr, "glUniform4d"); + context->Uniform4dv = (PFNGLUNIFORM4DVPROC) load(userptr, "glUniform4dv"); + context->UniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC) load(userptr, "glUniformMatrix2dv"); + context->UniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC) load(userptr, "glUniformMatrix2x3dv"); + context->UniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC) load(userptr, "glUniformMatrix2x4dv"); + context->UniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC) load(userptr, "glUniformMatrix3dv"); + context->UniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC) load(userptr, "glUniformMatrix3x2dv"); + context->UniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC) load(userptr, "glUniformMatrix3x4dv"); + context->UniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC) load(userptr, "glUniformMatrix4dv"); + context->UniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC) load(userptr, "glUniformMatrix4x2dv"); + context->UniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC) load(userptr, "glUniformMatrix4x3dv"); + context->UniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC) load(userptr, "glUniformSubroutinesuiv"); +} +static void glad_gl_load_GL_VERSION_4_1(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_4_1) return; + context->ActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC) load(userptr, "glActiveShaderProgram"); + context->BindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC) load(userptr, "glBindProgramPipeline"); + context->ClearDepthf = (PFNGLCLEARDEPTHFPROC) load(userptr, "glClearDepthf"); + context->CreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC) load(userptr, "glCreateShaderProgramv"); + context->DeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC) load(userptr, "glDeleteProgramPipelines"); + context->DepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC) load(userptr, "glDepthRangeArrayv"); + context->DepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC) load(userptr, "glDepthRangeIndexed"); + context->DepthRangef = (PFNGLDEPTHRANGEFPROC) load(userptr, "glDepthRangef"); + context->GenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC) load(userptr, "glGenProgramPipelines"); + context->GetDoublei_v = (PFNGLGETDOUBLEI_VPROC) load(userptr, "glGetDoublei_v"); + context->GetFloati_v = (PFNGLGETFLOATI_VPROC) load(userptr, "glGetFloati_v"); + context->GetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) load(userptr, "glGetProgramBinary"); + context->GetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC) load(userptr, "glGetProgramPipelineInfoLog"); + context->GetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC) load(userptr, "glGetProgramPipelineiv"); + context->GetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) load(userptr, "glGetShaderPrecisionFormat"); + context->GetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC) load(userptr, "glGetVertexAttribLdv"); + context->IsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC) load(userptr, "glIsProgramPipeline"); + context->ProgramBinary = (PFNGLPROGRAMBINARYPROC) load(userptr, "glProgramBinary"); + context->ProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) load(userptr, "glProgramParameteri"); + context->ProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC) load(userptr, "glProgramUniform1d"); + context->ProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC) load(userptr, "glProgramUniform1dv"); + context->ProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC) load(userptr, "glProgramUniform1f"); + context->ProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC) load(userptr, "glProgramUniform1fv"); + context->ProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC) load(userptr, "glProgramUniform1i"); + context->ProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC) load(userptr, "glProgramUniform1iv"); + context->ProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC) load(userptr, "glProgramUniform1ui"); + context->ProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC) load(userptr, "glProgramUniform1uiv"); + context->ProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC) load(userptr, "glProgramUniform2d"); + context->ProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC) load(userptr, "glProgramUniform2dv"); + context->ProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC) load(userptr, "glProgramUniform2f"); + context->ProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC) load(userptr, "glProgramUniform2fv"); + context->ProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC) load(userptr, "glProgramUniform2i"); + context->ProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC) load(userptr, "glProgramUniform2iv"); + context->ProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC) load(userptr, "glProgramUniform2ui"); + context->ProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC) load(userptr, "glProgramUniform2uiv"); + context->ProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC) load(userptr, "glProgramUniform3d"); + context->ProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC) load(userptr, "glProgramUniform3dv"); + context->ProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC) load(userptr, "glProgramUniform3f"); + context->ProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC) load(userptr, "glProgramUniform3fv"); + context->ProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC) load(userptr, "glProgramUniform3i"); + context->ProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC) load(userptr, "glProgramUniform3iv"); + context->ProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC) load(userptr, "glProgramUniform3ui"); + context->ProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC) load(userptr, "glProgramUniform3uiv"); + context->ProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC) load(userptr, "glProgramUniform4d"); + context->ProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC) load(userptr, "glProgramUniform4dv"); + context->ProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC) load(userptr, "glProgramUniform4f"); + context->ProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC) load(userptr, "glProgramUniform4fv"); + context->ProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC) load(userptr, "glProgramUniform4i"); + context->ProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC) load(userptr, "glProgramUniform4iv"); + context->ProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC) load(userptr, "glProgramUniform4ui"); + context->ProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC) load(userptr, "glProgramUniform4uiv"); + context->ProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC) load(userptr, "glProgramUniformMatrix2dv"); + context->ProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC) load(userptr, "glProgramUniformMatrix2fv"); + context->ProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) load(userptr, "glProgramUniformMatrix2x3dv"); + context->ProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) load(userptr, "glProgramUniformMatrix2x3fv"); + context->ProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) load(userptr, "glProgramUniformMatrix2x4dv"); + context->ProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) load(userptr, "glProgramUniformMatrix2x4fv"); + context->ProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC) load(userptr, "glProgramUniformMatrix3dv"); + context->ProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC) load(userptr, "glProgramUniformMatrix3fv"); + context->ProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) load(userptr, "glProgramUniformMatrix3x2dv"); + context->ProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) load(userptr, "glProgramUniformMatrix3x2fv"); + context->ProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) load(userptr, "glProgramUniformMatrix3x4dv"); + context->ProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) load(userptr, "glProgramUniformMatrix3x4fv"); + context->ProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC) load(userptr, "glProgramUniformMatrix4dv"); + context->ProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC) load(userptr, "glProgramUniformMatrix4fv"); + context->ProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) load(userptr, "glProgramUniformMatrix4x2dv"); + context->ProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) load(userptr, "glProgramUniformMatrix4x2fv"); + context->ProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) load(userptr, "glProgramUniformMatrix4x3dv"); + context->ProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) load(userptr, "glProgramUniformMatrix4x3fv"); + context->ReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) load(userptr, "glReleaseShaderCompiler"); + context->ScissorArrayv = (PFNGLSCISSORARRAYVPROC) load(userptr, "glScissorArrayv"); + context->ScissorIndexed = (PFNGLSCISSORINDEXEDPROC) load(userptr, "glScissorIndexed"); + context->ScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC) load(userptr, "glScissorIndexedv"); + context->ShaderBinary = (PFNGLSHADERBINARYPROC) load(userptr, "glShaderBinary"); + context->UseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC) load(userptr, "glUseProgramStages"); + context->ValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC) load(userptr, "glValidateProgramPipeline"); + context->VertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC) load(userptr, "glVertexAttribL1d"); + context->VertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC) load(userptr, "glVertexAttribL1dv"); + context->VertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC) load(userptr, "glVertexAttribL2d"); + context->VertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC) load(userptr, "glVertexAttribL2dv"); + context->VertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC) load(userptr, "glVertexAttribL3d"); + context->VertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC) load(userptr, "glVertexAttribL3dv"); + context->VertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC) load(userptr, "glVertexAttribL4d"); + context->VertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC) load(userptr, "glVertexAttribL4dv"); + context->VertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC) load(userptr, "glVertexAttribLPointer"); + context->ViewportArrayv = (PFNGLVIEWPORTARRAYVPROC) load(userptr, "glViewportArrayv"); + context->ViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC) load(userptr, "glViewportIndexedf"); + context->ViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC) load(userptr, "glViewportIndexedfv"); +} +static void glad_gl_load_GL_VERSION_4_2(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_4_2) return; + context->BindImageTexture = (PFNGLBINDIMAGETEXTUREPROC) load(userptr, "glBindImageTexture"); + context->DrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) load(userptr, "glDrawArraysInstancedBaseInstance"); + context->DrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) load(userptr, "glDrawElementsInstancedBaseInstance"); + context->DrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) load(userptr, "glDrawElementsInstancedBaseVertexBaseInstance"); + context->DrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) load(userptr, "glDrawTransformFeedbackInstanced"); + context->DrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) load(userptr, "glDrawTransformFeedbackStreamInstanced"); + context->GetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) load(userptr, "glGetActiveAtomicCounterBufferiv"); + context->GetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC) load(userptr, "glGetInternalformativ"); + context->MemoryBarrier = (PFNGLMEMORYBARRIERPROC) load(userptr, "glMemoryBarrier"); + context->TexStorage1D = (PFNGLTEXSTORAGE1DPROC) load(userptr, "glTexStorage1D"); + context->TexStorage2D = (PFNGLTEXSTORAGE2DPROC) load(userptr, "glTexStorage2D"); + context->TexStorage3D = (PFNGLTEXSTORAGE3DPROC) load(userptr, "glTexStorage3D"); +} +static void glad_gl_load_GL_VERSION_4_3(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_4_3) return; + context->BindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC) load(userptr, "glBindVertexBuffer"); + context->ClearBufferData = (PFNGLCLEARBUFFERDATAPROC) load(userptr, "glClearBufferData"); + context->ClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC) load(userptr, "glClearBufferSubData"); + context->CopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC) load(userptr, "glCopyImageSubData"); + context->DebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC) load(userptr, "glDebugMessageCallback"); + context->DebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC) load(userptr, "glDebugMessageControl"); + context->DebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC) load(userptr, "glDebugMessageInsert"); + context->DispatchCompute = (PFNGLDISPATCHCOMPUTEPROC) load(userptr, "glDispatchCompute"); + context->DispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC) load(userptr, "glDispatchComputeIndirect"); + context->FramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC) load(userptr, "glFramebufferParameteri"); + context->GetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC) load(userptr, "glGetDebugMessageLog"); + context->GetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC) load(userptr, "glGetFramebufferParameteriv"); + context->GetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC) load(userptr, "glGetInternalformati64v"); + context->GetObjectLabel = (PFNGLGETOBJECTLABELPROC) load(userptr, "glGetObjectLabel"); + context->GetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC) load(userptr, "glGetObjectPtrLabel"); + context->GetPointerv = (PFNGLGETPOINTERVPROC) load(userptr, "glGetPointerv"); + context->GetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC) load(userptr, "glGetProgramInterfaceiv"); + context->GetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC) load(userptr, "glGetProgramResourceIndex"); + context->GetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC) load(userptr, "glGetProgramResourceLocation"); + context->GetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) load(userptr, "glGetProgramResourceLocationIndex"); + context->GetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC) load(userptr, "glGetProgramResourceName"); + context->GetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC) load(userptr, "glGetProgramResourceiv"); + context->InvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC) load(userptr, "glInvalidateBufferData"); + context->InvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC) load(userptr, "glInvalidateBufferSubData"); + context->InvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC) load(userptr, "glInvalidateFramebuffer"); + context->InvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC) load(userptr, "glInvalidateSubFramebuffer"); + context->InvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC) load(userptr, "glInvalidateTexImage"); + context->InvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC) load(userptr, "glInvalidateTexSubImage"); + context->MultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC) load(userptr, "glMultiDrawArraysIndirect"); + context->MultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC) load(userptr, "glMultiDrawElementsIndirect"); + context->ObjectLabel = (PFNGLOBJECTLABELPROC) load(userptr, "glObjectLabel"); + context->ObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC) load(userptr, "glObjectPtrLabel"); + context->PopDebugGroup = (PFNGLPOPDEBUGGROUPPROC) load(userptr, "glPopDebugGroup"); + context->PushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC) load(userptr, "glPushDebugGroup"); + context->ShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC) load(userptr, "glShaderStorageBlockBinding"); + context->TexBufferRange = (PFNGLTEXBUFFERRANGEPROC) load(userptr, "glTexBufferRange"); + context->TexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC) load(userptr, "glTexStorage2DMultisample"); + context->TexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC) load(userptr, "glTexStorage3DMultisample"); + context->TextureView = (PFNGLTEXTUREVIEWPROC) load(userptr, "glTextureView"); + context->VertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC) load(userptr, "glVertexAttribBinding"); + context->VertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC) load(userptr, "glVertexAttribFormat"); + context->VertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC) load(userptr, "glVertexAttribIFormat"); + context->VertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC) load(userptr, "glVertexAttribLFormat"); + context->VertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC) load(userptr, "glVertexBindingDivisor"); +} +static void glad_gl_load_GL_VERSION_4_4(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_4_4) return; + context->BindBuffersBase = (PFNGLBINDBUFFERSBASEPROC) load(userptr, "glBindBuffersBase"); + context->BindBuffersRange = (PFNGLBINDBUFFERSRANGEPROC) load(userptr, "glBindBuffersRange"); + context->BindImageTextures = (PFNGLBINDIMAGETEXTURESPROC) load(userptr, "glBindImageTextures"); + context->BindSamplers = (PFNGLBINDSAMPLERSPROC) load(userptr, "glBindSamplers"); + context->BindTextures = (PFNGLBINDTEXTURESPROC) load(userptr, "glBindTextures"); + context->BindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC) load(userptr, "glBindVertexBuffers"); + context->BufferStorage = (PFNGLBUFFERSTORAGEPROC) load(userptr, "glBufferStorage"); + context->ClearTexImage = (PFNGLCLEARTEXIMAGEPROC) load(userptr, "glClearTexImage"); + context->ClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC) load(userptr, "glClearTexSubImage"); +} +static void glad_gl_load_GL_VERSION_4_5(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_4_5) return; + context->BindTextureUnit = (PFNGLBINDTEXTUREUNITPROC) load(userptr, "glBindTextureUnit"); + context->BlitNamedFramebuffer = (PFNGLBLITNAMEDFRAMEBUFFERPROC) load(userptr, "glBlitNamedFramebuffer"); + context->CheckNamedFramebufferStatus = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckNamedFramebufferStatus"); + context->ClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATAPROC) load(userptr, "glClearNamedBufferData"); + context->ClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATAPROC) load(userptr, "glClearNamedBufferSubData"); + context->ClearNamedFramebufferfi = (PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) load(userptr, "glClearNamedFramebufferfi"); + context->ClearNamedFramebufferfv = (PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) load(userptr, "glClearNamedFramebufferfv"); + context->ClearNamedFramebufferiv = (PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) load(userptr, "glClearNamedFramebufferiv"); + context->ClearNamedFramebufferuiv = (PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) load(userptr, "glClearNamedFramebufferuiv"); + context->ClipControl = (PFNGLCLIPCONTROLPROC) load(userptr, "glClipControl"); + context->CompressedTextureSubImage1D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) load(userptr, "glCompressedTextureSubImage1D"); + context->CompressedTextureSubImage2D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) load(userptr, "glCompressedTextureSubImage2D"); + context->CompressedTextureSubImage3D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) load(userptr, "glCompressedTextureSubImage3D"); + context->CopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATAPROC) load(userptr, "glCopyNamedBufferSubData"); + context->CopyTextureSubImage1D = (PFNGLCOPYTEXTURESUBIMAGE1DPROC) load(userptr, "glCopyTextureSubImage1D"); + context->CopyTextureSubImage2D = (PFNGLCOPYTEXTURESUBIMAGE2DPROC) load(userptr, "glCopyTextureSubImage2D"); + context->CopyTextureSubImage3D = (PFNGLCOPYTEXTURESUBIMAGE3DPROC) load(userptr, "glCopyTextureSubImage3D"); + context->CreateBuffers = (PFNGLCREATEBUFFERSPROC) load(userptr, "glCreateBuffers"); + context->CreateFramebuffers = (PFNGLCREATEFRAMEBUFFERSPROC) load(userptr, "glCreateFramebuffers"); + context->CreateProgramPipelines = (PFNGLCREATEPROGRAMPIPELINESPROC) load(userptr, "glCreateProgramPipelines"); + context->CreateQueries = (PFNGLCREATEQUERIESPROC) load(userptr, "glCreateQueries"); + context->CreateRenderbuffers = (PFNGLCREATERENDERBUFFERSPROC) load(userptr, "glCreateRenderbuffers"); + context->CreateSamplers = (PFNGLCREATESAMPLERSPROC) load(userptr, "glCreateSamplers"); + context->CreateTextures = (PFNGLCREATETEXTURESPROC) load(userptr, "glCreateTextures"); + context->CreateTransformFeedbacks = (PFNGLCREATETRANSFORMFEEDBACKSPROC) load(userptr, "glCreateTransformFeedbacks"); + context->CreateVertexArrays = (PFNGLCREATEVERTEXARRAYSPROC) load(userptr, "glCreateVertexArrays"); + context->DisableVertexArrayAttrib = (PFNGLDISABLEVERTEXARRAYATTRIBPROC) load(userptr, "glDisableVertexArrayAttrib"); + context->EnableVertexArrayAttrib = (PFNGLENABLEVERTEXARRAYATTRIBPROC) load(userptr, "glEnableVertexArrayAttrib"); + context->FlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) load(userptr, "glFlushMappedNamedBufferRange"); + context->GenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC) load(userptr, "glGenerateTextureMipmap"); + context->GetCompressedTextureImage = (PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) load(userptr, "glGetCompressedTextureImage"); + context->GetCompressedTextureSubImage = (PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) load(userptr, "glGetCompressedTextureSubImage"); + context->GetGraphicsResetStatus = (PFNGLGETGRAPHICSRESETSTATUSPROC) load(userptr, "glGetGraphicsResetStatus"); + context->GetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) load(userptr, "glGetNamedBufferParameteri64v"); + context->GetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedBufferParameteriv"); + context->GetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERVPROC) load(userptr, "glGetNamedBufferPointerv"); + context->GetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATAPROC) load(userptr, "glGetNamedBufferSubData"); + context->GetNamedFramebufferAttachmentParameteriv = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetNamedFramebufferAttachmentParameteriv"); + context->GetNamedFramebufferParameteriv = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedFramebufferParameteriv"); + context->GetNamedRenderbufferParameteriv = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedRenderbufferParameteriv"); + context->GetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECTI64VPROC) load(userptr, "glGetQueryBufferObjecti64v"); + context->GetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECTIVPROC) load(userptr, "glGetQueryBufferObjectiv"); + context->GetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECTUI64VPROC) load(userptr, "glGetQueryBufferObjectui64v"); + context->GetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECTUIVPROC) load(userptr, "glGetQueryBufferObjectuiv"); + context->GetTextureImage = (PFNGLGETTEXTUREIMAGEPROC) load(userptr, "glGetTextureImage"); + context->GetTextureLevelParameterfv = (PFNGLGETTEXTURELEVELPARAMETERFVPROC) load(userptr, "glGetTextureLevelParameterfv"); + context->GetTextureLevelParameteriv = (PFNGLGETTEXTURELEVELPARAMETERIVPROC) load(userptr, "glGetTextureLevelParameteriv"); + context->GetTextureParameterIiv = (PFNGLGETTEXTUREPARAMETERIIVPROC) load(userptr, "glGetTextureParameterIiv"); + context->GetTextureParameterIuiv = (PFNGLGETTEXTUREPARAMETERIUIVPROC) load(userptr, "glGetTextureParameterIuiv"); + context->GetTextureParameterfv = (PFNGLGETTEXTUREPARAMETERFVPROC) load(userptr, "glGetTextureParameterfv"); + context->GetTextureParameteriv = (PFNGLGETTEXTUREPARAMETERIVPROC) load(userptr, "glGetTextureParameteriv"); + context->GetTextureSubImage = (PFNGLGETTEXTURESUBIMAGEPROC) load(userptr, "glGetTextureSubImage"); + context->GetTransformFeedbacki64_v = (PFNGLGETTRANSFORMFEEDBACKI64_VPROC) load(userptr, "glGetTransformFeedbacki64_v"); + context->GetTransformFeedbacki_v = (PFNGLGETTRANSFORMFEEDBACKI_VPROC) load(userptr, "glGetTransformFeedbacki_v"); + context->GetTransformFeedbackiv = (PFNGLGETTRANSFORMFEEDBACKIVPROC) load(userptr, "glGetTransformFeedbackiv"); + context->GetVertexArrayIndexed64iv = (PFNGLGETVERTEXARRAYINDEXED64IVPROC) load(userptr, "glGetVertexArrayIndexed64iv"); + context->GetVertexArrayIndexediv = (PFNGLGETVERTEXARRAYINDEXEDIVPROC) load(userptr, "glGetVertexArrayIndexediv"); + context->GetVertexArrayiv = (PFNGLGETVERTEXARRAYIVPROC) load(userptr, "glGetVertexArrayiv"); + context->GetnColorTable = (PFNGLGETNCOLORTABLEPROC) load(userptr, "glGetnColorTable"); + context->GetnCompressedTexImage = (PFNGLGETNCOMPRESSEDTEXIMAGEPROC) load(userptr, "glGetnCompressedTexImage"); + context->GetnConvolutionFilter = (PFNGLGETNCONVOLUTIONFILTERPROC) load(userptr, "glGetnConvolutionFilter"); + context->GetnHistogram = (PFNGLGETNHISTOGRAMPROC) load(userptr, "glGetnHistogram"); + context->GetnMapdv = (PFNGLGETNMAPDVPROC) load(userptr, "glGetnMapdv"); + context->GetnMapfv = (PFNGLGETNMAPFVPROC) load(userptr, "glGetnMapfv"); + context->GetnMapiv = (PFNGLGETNMAPIVPROC) load(userptr, "glGetnMapiv"); + context->GetnMinmax = (PFNGLGETNMINMAXPROC) load(userptr, "glGetnMinmax"); + context->GetnPixelMapfv = (PFNGLGETNPIXELMAPFVPROC) load(userptr, "glGetnPixelMapfv"); + context->GetnPixelMapuiv = (PFNGLGETNPIXELMAPUIVPROC) load(userptr, "glGetnPixelMapuiv"); + context->GetnPixelMapusv = (PFNGLGETNPIXELMAPUSVPROC) load(userptr, "glGetnPixelMapusv"); + context->GetnPolygonStipple = (PFNGLGETNPOLYGONSTIPPLEPROC) load(userptr, "glGetnPolygonStipple"); + context->GetnSeparableFilter = (PFNGLGETNSEPARABLEFILTERPROC) load(userptr, "glGetnSeparableFilter"); + context->GetnTexImage = (PFNGLGETNTEXIMAGEPROC) load(userptr, "glGetnTexImage"); + context->GetnUniformdv = (PFNGLGETNUNIFORMDVPROC) load(userptr, "glGetnUniformdv"); + context->GetnUniformfv = (PFNGLGETNUNIFORMFVPROC) load(userptr, "glGetnUniformfv"); + context->GetnUniformiv = (PFNGLGETNUNIFORMIVPROC) load(userptr, "glGetnUniformiv"); + context->GetnUniformuiv = (PFNGLGETNUNIFORMUIVPROC) load(userptr, "glGetnUniformuiv"); + context->InvalidateNamedFramebufferData = (PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) load(userptr, "glInvalidateNamedFramebufferData"); + context->InvalidateNamedFramebufferSubData = (PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) load(userptr, "glInvalidateNamedFramebufferSubData"); + context->MapNamedBuffer = (PFNGLMAPNAMEDBUFFERPROC) load(userptr, "glMapNamedBuffer"); + context->MapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGEPROC) load(userptr, "glMapNamedBufferRange"); + context->MemoryBarrierByRegion = (PFNGLMEMORYBARRIERBYREGIONPROC) load(userptr, "glMemoryBarrierByRegion"); + context->NamedBufferData = (PFNGLNAMEDBUFFERDATAPROC) load(userptr, "glNamedBufferData"); + context->NamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGEPROC) load(userptr, "glNamedBufferStorage"); + context->NamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATAPROC) load(userptr, "glNamedBufferSubData"); + context->NamedFramebufferDrawBuffer = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) load(userptr, "glNamedFramebufferDrawBuffer"); + context->NamedFramebufferDrawBuffers = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) load(userptr, "glNamedFramebufferDrawBuffers"); + context->NamedFramebufferParameteri = (PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) load(userptr, "glNamedFramebufferParameteri"); + context->NamedFramebufferReadBuffer = (PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) load(userptr, "glNamedFramebufferReadBuffer"); + context->NamedFramebufferRenderbuffer = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glNamedFramebufferRenderbuffer"); + context->NamedFramebufferTexture = (PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) load(userptr, "glNamedFramebufferTexture"); + context->NamedFramebufferTextureLayer = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glNamedFramebufferTextureLayer"); + context->NamedRenderbufferStorage = (PFNGLNAMEDRENDERBUFFERSTORAGEPROC) load(userptr, "glNamedRenderbufferStorage"); + context->NamedRenderbufferStorageMultisample = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glNamedRenderbufferStorageMultisample"); + context->ReadnPixels = (PFNGLREADNPIXELSPROC) load(userptr, "glReadnPixels"); + context->TextureBarrier = (PFNGLTEXTUREBARRIERPROC) load(userptr, "glTextureBarrier"); + context->TextureBuffer = (PFNGLTEXTUREBUFFERPROC) load(userptr, "glTextureBuffer"); + context->TextureBufferRange = (PFNGLTEXTUREBUFFERRANGEPROC) load(userptr, "glTextureBufferRange"); + context->TextureParameterIiv = (PFNGLTEXTUREPARAMETERIIVPROC) load(userptr, "glTextureParameterIiv"); + context->TextureParameterIuiv = (PFNGLTEXTUREPARAMETERIUIVPROC) load(userptr, "glTextureParameterIuiv"); + context->TextureParameterf = (PFNGLTEXTUREPARAMETERFPROC) load(userptr, "glTextureParameterf"); + context->TextureParameterfv = (PFNGLTEXTUREPARAMETERFVPROC) load(userptr, "glTextureParameterfv"); + context->TextureParameteri = (PFNGLTEXTUREPARAMETERIPROC) load(userptr, "glTextureParameteri"); + context->TextureParameteriv = (PFNGLTEXTUREPARAMETERIVPROC) load(userptr, "glTextureParameteriv"); + context->TextureStorage1D = (PFNGLTEXTURESTORAGE1DPROC) load(userptr, "glTextureStorage1D"); + context->TextureStorage2D = (PFNGLTEXTURESTORAGE2DPROC) load(userptr, "glTextureStorage2D"); + context->TextureStorage2DMultisample = (PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) load(userptr, "glTextureStorage2DMultisample"); + context->TextureStorage3D = (PFNGLTEXTURESTORAGE3DPROC) load(userptr, "glTextureStorage3D"); + context->TextureStorage3DMultisample = (PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) load(userptr, "glTextureStorage3DMultisample"); + context->TextureSubImage1D = (PFNGLTEXTURESUBIMAGE1DPROC) load(userptr, "glTextureSubImage1D"); + context->TextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC) load(userptr, "glTextureSubImage2D"); + context->TextureSubImage3D = (PFNGLTEXTURESUBIMAGE3DPROC) load(userptr, "glTextureSubImage3D"); + context->TransformFeedbackBufferBase = (PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) load(userptr, "glTransformFeedbackBufferBase"); + context->TransformFeedbackBufferRange = (PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) load(userptr, "glTransformFeedbackBufferRange"); + context->UnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC) load(userptr, "glUnmapNamedBuffer"); + context->VertexArrayAttribBinding = (PFNGLVERTEXARRAYATTRIBBINDINGPROC) load(userptr, "glVertexArrayAttribBinding"); + context->VertexArrayAttribFormat = (PFNGLVERTEXARRAYATTRIBFORMATPROC) load(userptr, "glVertexArrayAttribFormat"); + context->VertexArrayAttribIFormat = (PFNGLVERTEXARRAYATTRIBIFORMATPROC) load(userptr, "glVertexArrayAttribIFormat"); + context->VertexArrayAttribLFormat = (PFNGLVERTEXARRAYATTRIBLFORMATPROC) load(userptr, "glVertexArrayAttribLFormat"); + context->VertexArrayBindingDivisor = (PFNGLVERTEXARRAYBINDINGDIVISORPROC) load(userptr, "glVertexArrayBindingDivisor"); + context->VertexArrayElementBuffer = (PFNGLVERTEXARRAYELEMENTBUFFERPROC) load(userptr, "glVertexArrayElementBuffer"); + context->VertexArrayVertexBuffer = (PFNGLVERTEXARRAYVERTEXBUFFERPROC) load(userptr, "glVertexArrayVertexBuffer"); + context->VertexArrayVertexBuffers = (PFNGLVERTEXARRAYVERTEXBUFFERSPROC) load(userptr, "glVertexArrayVertexBuffers"); +} +static void glad_gl_load_GL_VERSION_4_6(GladGLContext *context, GLADuserptrloadfunc load, void* userptr) { + if(!context->VERSION_4_6) return; + context->MultiDrawArraysIndirectCount = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC) load(userptr, "glMultiDrawArraysIndirectCount"); + context->MultiDrawElementsIndirectCount = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC) load(userptr, "glMultiDrawElementsIndirectCount"); + context->PolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPPROC) load(userptr, "glPolygonOffsetClamp"); + context->SpecializeShader = (PFNGLSPECIALIZESHADERPROC) load(userptr, "glSpecializeShader"); +} + + + +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(GladGLContext *context, const char **out_exts, char ***out_exts_i) { +#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) + if (context->GetStringi != NULL && context->GetIntegerv != NULL) { + unsigned int index = 0; + unsigned int num_exts_i = 0; + char **exts_i = NULL; + context->GetIntegerv(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*) context->GetStringi(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 (context->GetString == NULL) { + return 0; + } + *out_exts = (const char *)context->GetString(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(GladGLContext *context) { + const char *exts = NULL; + char **exts_i = NULL; + if (!glad_gl_get_extensions(context, &exts, &exts_i)) return 0; + + GLAD_UNUSED(&glad_gl_has_extension); + + glad_gl_free_extensions(exts_i); + + return 1; +} + +static int glad_gl_find_core_gl(GladGLContext *context) { + 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*) context->GetString(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); + + context->VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; + context->VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; + context->VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; + context->VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; + context->VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; + context->VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; + context->VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; + context->VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; + context->VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; + context->VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; + context->VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; + context->VERSION_3_3 = (major == 3 && minor >= 3) || major > 3; + context->VERSION_4_0 = (major == 4 && minor >= 0) || major > 4; + context->VERSION_4_1 = (major == 4 && minor >= 1) || major > 4; + context->VERSION_4_2 = (major == 4 && minor >= 2) || major > 4; + context->VERSION_4_3 = (major == 4 && minor >= 3) || major > 4; + context->VERSION_4_4 = (major == 4 && minor >= 4) || major > 4; + context->VERSION_4_5 = (major == 4 && minor >= 5) || major > 4; + context->VERSION_4_6 = (major == 4 && minor >= 6) || major > 4; + + return GLAD_MAKE_VERSION(major, minor); +} + +int gladLoadGLContextUserPtr(GladGLContext *context, GLADuserptrloadfunc load, void *userptr) { + int version; + + context->GetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString"); + if(context->GetString == NULL) return 0; + version = glad_gl_find_core_gl(context); + + glad_gl_load_GL_VERSION_1_0(context, load, userptr); + glad_gl_load_GL_VERSION_1_1(context, load, userptr); + glad_gl_load_GL_VERSION_1_2(context, load, userptr); + glad_gl_load_GL_VERSION_1_3(context, load, userptr); + glad_gl_load_GL_VERSION_1_4(context, load, userptr); + glad_gl_load_GL_VERSION_1_5(context, load, userptr); + glad_gl_load_GL_VERSION_2_0(context, load, userptr); + glad_gl_load_GL_VERSION_2_1(context, load, userptr); + glad_gl_load_GL_VERSION_3_0(context, load, userptr); + glad_gl_load_GL_VERSION_3_1(context, load, userptr); + glad_gl_load_GL_VERSION_3_2(context, load, userptr); + glad_gl_load_GL_VERSION_3_3(context, load, userptr); + glad_gl_load_GL_VERSION_4_0(context, load, userptr); + glad_gl_load_GL_VERSION_4_1(context, load, userptr); + glad_gl_load_GL_VERSION_4_2(context, load, userptr); + glad_gl_load_GL_VERSION_4_3(context, load, userptr); + glad_gl_load_GL_VERSION_4_4(context, load, userptr); + glad_gl_load_GL_VERSION_4_5(context, load, userptr); + glad_gl_load_GL_VERSION_4_6(context, load, userptr); + + if (!glad_gl_find_extensions_gl(context)) return 0; + + + + return version; +} + + +int gladLoadGLContext(GladGLContext *context, GLADloadfunc load) { + return gladLoadGLContextUserPtr(context, glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +} + + + + + + +#ifdef __cplusplus +} +#endif diff --git a/mplot/glad/gl.h b/mplot/glad/gl.h index 9e92a8db..390b8b1a 100644 --- a/mplot/glad/gl.h +++ b/mplot/glad/gl.h @@ -1,5 +1,5 @@ /** - * Loader generated by glad 2.0.8 on Thu Feb 27 15:08:21 2025 + * Loader generated by glad 2.0.8 on Fri Mar 6 13:00:56 2026 * * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 * @@ -13,16 +13,16 @@ * Options: * - ALIAS = False * - DEBUG = False - * - HEADER_ONLY = True + * - HEADER_ONLY = False * - LOADER = False - * - MX = False + * - MX = True * - ON_DEMAND = False * * Commandline: - * --api='gl:compatibility=4.6' --extensions='' c --header-only + * --api='gl:compatibility=4.6' --extensions='' c --mx * * Online: - * http://glad.sh/#api=gl%3Acompatibility%3D4.6&extensions=&generator=c&options=HEADER_ONLY + * http://glad.sh/#api=gl%3Acompatibility%3D4.6&extensions=&generator=c&options=MX * */ @@ -54,7 +54,7 @@ #endif #define GLAD_GL -#define GLAD_OPTION_GL_HEADER_ONLY +#define GLAD_OPTION_GL_MX #ifdef __cplusplus extern "C" { @@ -1986,317 +1986,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #define GL_ZOOM_Y 0x0D17 -#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_GLAD_API_PTR - * KHRONOS_APIATTRIBUTES - * - * These may be used in function prototypes as: - * - * KHRONOS_APICALL void KHRONOS_GLAD_API_PTR 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_GLAD_API_PTR - *------------------------------------------------------------------------- - * 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_GLAD_API_PTR __stdcall -#else -# define KHRONOS_GLAD_API_PTR -#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_ */ +#include typedef unsigned int GLenum; typedef unsigned char GLboolean; typedef unsigned int GLbitfield; @@ -2362,43 +2052,24 @@ 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; typedef void (GLAD_API_PTR *PFNGLACCUMPROC)(GLenum op, GLfloat value); @@ -3450,4521 +3121,1091 @@ typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3IVPROC)(const GLint * v); typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3SPROC)(GLshort x, GLshort y, GLshort z); typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3SVPROC)(const GLshort * v); -GLAD_API_CALL PFNGLACCUMPROC glad_glAccum; -#define glAccum glad_glAccum -GLAD_API_CALL PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram; -#define glActiveShaderProgram glad_glActiveShaderProgram -GLAD_API_CALL PFNGLACTIVETEXTUREPROC glad_glActiveTexture; -#define glActiveTexture glad_glActiveTexture -GLAD_API_CALL PFNGLALPHAFUNCPROC glad_glAlphaFunc; -#define glAlphaFunc glad_glAlphaFunc -GLAD_API_CALL PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident; -#define glAreTexturesResident glad_glAreTexturesResident -GLAD_API_CALL PFNGLARRAYELEMENTPROC glad_glArrayElement; -#define glArrayElement glad_glArrayElement -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 PFNGLBEGINQUERYPROC glad_glBeginQuery; -#define glBeginQuery glad_glBeginQuery -GLAD_API_CALL PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed; -#define glBeginQueryIndexed glad_glBeginQueryIndexed -GLAD_API_CALL PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; -#define glBeginTransformFeedback glad_glBeginTransformFeedback -GLAD_API_CALL PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; -#define glBindAttribLocation glad_glBindAttribLocation -GLAD_API_CALL PFNGLBINDBUFFERPROC glad_glBindBuffer; -#define glBindBuffer glad_glBindBuffer -GLAD_API_CALL PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; -#define glBindBufferBase glad_glBindBufferBase -GLAD_API_CALL PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; -#define glBindBufferRange glad_glBindBufferRange -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 PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed; -#define glBindFragDataLocationIndexed glad_glBindFragDataLocationIndexed -GLAD_API_CALL PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; -#define glBindFramebuffer glad_glBindFramebuffer -GLAD_API_CALL PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture; -#define glBindImageTexture glad_glBindImageTexture -GLAD_API_CALL PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures; -#define glBindImageTextures glad_glBindImageTextures -GLAD_API_CALL PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline; -#define glBindProgramPipeline glad_glBindProgramPipeline -GLAD_API_CALL PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; -#define glBindRenderbuffer glad_glBindRenderbuffer -GLAD_API_CALL PFNGLBINDSAMPLERPROC glad_glBindSampler; -#define glBindSampler glad_glBindSampler -GLAD_API_CALL PFNGLBINDSAMPLERSPROC glad_glBindSamplers; -#define glBindSamplers glad_glBindSamplers -GLAD_API_CALL PFNGLBINDTEXTUREPROC glad_glBindTexture; -#define glBindTexture glad_glBindTexture -GLAD_API_CALL PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit; -#define glBindTextureUnit glad_glBindTextureUnit -GLAD_API_CALL PFNGLBINDTEXTURESPROC glad_glBindTextures; -#define glBindTextures glad_glBindTextures -GLAD_API_CALL PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback; -#define glBindTransformFeedback glad_glBindTransformFeedback -GLAD_API_CALL PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; -#define glBindVertexArray glad_glBindVertexArray -GLAD_API_CALL PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer; -#define glBindVertexBuffer glad_glBindVertexBuffer -GLAD_API_CALL PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers; -#define glBindVertexBuffers glad_glBindVertexBuffers -GLAD_API_CALL PFNGLBITMAPPROC glad_glBitmap; -#define glBitmap glad_glBitmap -GLAD_API_CALL PFNGLBLENDCOLORPROC glad_glBlendColor; -#define glBlendColor glad_glBlendColor -GLAD_API_CALL PFNGLBLENDEQUATIONPROC glad_glBlendEquation; -#define glBlendEquation glad_glBlendEquation -GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; -#define glBlendEquationSeparate glad_glBlendEquationSeparate -GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEIPROC glad_glBlendEquationSeparatei; -#define glBlendEquationSeparatei glad_glBlendEquationSeparatei -GLAD_API_CALL PFNGLBLENDEQUATIONIPROC glad_glBlendEquationi; -#define glBlendEquationi glad_glBlendEquationi -GLAD_API_CALL PFNGLBLENDFUNCPROC glad_glBlendFunc; -#define glBlendFunc glad_glBlendFunc -GLAD_API_CALL PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; -#define glBlendFuncSeparate glad_glBlendFuncSeparate -GLAD_API_CALL PFNGLBLENDFUNCSEPARATEIPROC glad_glBlendFuncSeparatei; -#define glBlendFuncSeparatei glad_glBlendFuncSeparatei -GLAD_API_CALL PFNGLBLENDFUNCIPROC glad_glBlendFunci; -#define glBlendFunci glad_glBlendFunci -GLAD_API_CALL PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; -#define glBlitFramebuffer glad_glBlitFramebuffer -GLAD_API_CALL PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer; -#define glBlitNamedFramebuffer glad_glBlitNamedFramebuffer -GLAD_API_CALL PFNGLBUFFERDATAPROC glad_glBufferData; -#define glBufferData glad_glBufferData -GLAD_API_CALL PFNGLBUFFERSTORAGEPROC glad_glBufferStorage; -#define glBufferStorage glad_glBufferStorage -GLAD_API_CALL PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; -#define glBufferSubData glad_glBufferSubData -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 PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus; -#define glCheckNamedFramebufferStatus glad_glCheckNamedFramebufferStatus -GLAD_API_CALL PFNGLCLAMPCOLORPROC glad_glClampColor; -#define glClampColor glad_glClampColor -GLAD_API_CALL PFNGLCLEARPROC glad_glClear; -#define glClear glad_glClear -GLAD_API_CALL PFNGLCLEARACCUMPROC glad_glClearAccum; -#define glClearAccum glad_glClearAccum -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 PFNGLCLEARDEPTHPROC glad_glClearDepth; -#define glClearDepth glad_glClearDepth -GLAD_API_CALL PFNGLCLEARDEPTHFPROC glad_glClearDepthf; -#define glClearDepthf glad_glClearDepthf -GLAD_API_CALL PFNGLCLEARINDEXPROC glad_glClearIndex; -#define glClearIndex glad_glClearIndex -GLAD_API_CALL PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData; -#define glClearNamedBufferData glad_glClearNamedBufferData -GLAD_API_CALL PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData; -#define glClearNamedBufferSubData glad_glClearNamedBufferSubData -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 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 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 PFNGLCOLOR3FVPROC glad_glColor3fv; -#define glColor3fv glad_glColor3fv -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 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 PFNGLCOLOR4FVPROC glad_glColor4fv; -#define glColor4fv glad_glColor4fv -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 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 PFNGLCOLORMASKPROC glad_glColorMask; -#define glColorMask glad_glColorMask -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 PFNGLCOMPILESHADERPROC glad_glCompileShader; -#define glCompileShader glad_glCompileShader -GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; -#define glCompressedTexImage1D glad_glCompressedTexImage1D -GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; -#define glCompressedTexImage2D glad_glCompressedTexImage2D -GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; -#define glCompressedTexImage3D glad_glCompressedTexImage3D -GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; -#define glCompressedTexSubImage1D glad_glCompressedTexSubImage1D -GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; -#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D -GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; -#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D -GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D; -#define glCompressedTextureSubImage1D glad_glCompressedTextureSubImage1D -GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D; -#define glCompressedTextureSubImage2D glad_glCompressedTextureSubImage2D -GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D; -#define glCompressedTextureSubImage3D glad_glCompressedTextureSubImage3D -GLAD_API_CALL PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; -#define glCopyBufferSubData glad_glCopyBufferSubData -GLAD_API_CALL PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData; -#define glCopyImageSubData glad_glCopyImageSubData -GLAD_API_CALL PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData; -#define glCopyNamedBufferSubData glad_glCopyNamedBufferSubData -GLAD_API_CALL PFNGLCOPYPIXELSPROC glad_glCopyPixels; -#define glCopyPixels glad_glCopyPixels -GLAD_API_CALL PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; -#define glCopyTexImage1D glad_glCopyTexImage1D -GLAD_API_CALL PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; -#define glCopyTexImage2D glad_glCopyTexImage2D -GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; -#define glCopyTexSubImage1D glad_glCopyTexSubImage1D -GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; -#define glCopyTexSubImage2D glad_glCopyTexSubImage2D -GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; -#define glCopyTexSubImage3D glad_glCopyTexSubImage3D -GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D; -#define glCopyTextureSubImage1D glad_glCopyTextureSubImage1D -GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D; -#define glCopyTextureSubImage2D glad_glCopyTextureSubImage2D -GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D; -#define glCopyTextureSubImage3D glad_glCopyTextureSubImage3D -GLAD_API_CALL PFNGLCREATEBUFFERSPROC glad_glCreateBuffers; -#define glCreateBuffers glad_glCreateBuffers -GLAD_API_CALL PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers; -#define glCreateFramebuffers glad_glCreateFramebuffers -GLAD_API_CALL PFNGLCREATEPROGRAMPROC glad_glCreateProgram; -#define glCreateProgram glad_glCreateProgram -GLAD_API_CALL PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines; -#define glCreateProgramPipelines glad_glCreateProgramPipelines -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 PFNGLCREATESHADERPROC glad_glCreateShader; -#define glCreateShader glad_glCreateShader -GLAD_API_CALL PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv; -#define glCreateShaderProgramv glad_glCreateShaderProgramv -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 PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback; -#define glDebugMessageCallback glad_glDebugMessageCallback -GLAD_API_CALL PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl; -#define glDebugMessageControl glad_glDebugMessageControl -GLAD_API_CALL PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert; -#define glDebugMessageInsert glad_glDebugMessageInsert -GLAD_API_CALL PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; -#define glDeleteBuffers glad_glDeleteBuffers -GLAD_API_CALL PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; -#define glDeleteFramebuffers glad_glDeleteFramebuffers -GLAD_API_CALL PFNGLDELETELISTSPROC glad_glDeleteLists; -#define glDeleteLists glad_glDeleteLists -GLAD_API_CALL PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; -#define glDeleteProgram glad_glDeleteProgram -GLAD_API_CALL PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines; -#define glDeleteProgramPipelines glad_glDeleteProgramPipelines -GLAD_API_CALL PFNGLDELETEQUERIESPROC glad_glDeleteQueries; -#define glDeleteQueries glad_glDeleteQueries -GLAD_API_CALL PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; -#define glDeleteRenderbuffers glad_glDeleteRenderbuffers -GLAD_API_CALL PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; -#define glDeleteSamplers glad_glDeleteSamplers -GLAD_API_CALL PFNGLDELETESHADERPROC glad_glDeleteShader; -#define glDeleteShader glad_glDeleteShader -GLAD_API_CALL PFNGLDELETESYNCPROC glad_glDeleteSync; -#define glDeleteSync glad_glDeleteSync -GLAD_API_CALL PFNGLDELETETEXTURESPROC glad_glDeleteTextures; -#define glDeleteTextures glad_glDeleteTextures -GLAD_API_CALL PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks; -#define glDeleteTransformFeedbacks glad_glDeleteTransformFeedbacks -GLAD_API_CALL PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; -#define glDeleteVertexArrays glad_glDeleteVertexArrays -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 PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv; -#define glDepthRangeArrayv glad_glDepthRangeArrayv -GLAD_API_CALL PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed; -#define glDepthRangeIndexed glad_glDepthRangeIndexed -GLAD_API_CALL PFNGLDEPTHRANGEFPROC glad_glDepthRangef; -#define glDepthRangef glad_glDepthRangef -GLAD_API_CALL PFNGLDETACHSHADERPROC glad_glDetachShader; -#define glDetachShader glad_glDetachShader -GLAD_API_CALL PFNGLDISABLEPROC glad_glDisable; -#define glDisable glad_glDisable -GLAD_API_CALL PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState; -#define glDisableClientState glad_glDisableClientState -GLAD_API_CALL PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib; -#define glDisableVertexArrayAttrib glad_glDisableVertexArrayAttrib -GLAD_API_CALL PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; -#define glDisableVertexAttribArray glad_glDisableVertexAttribArray -GLAD_API_CALL PFNGLDISABLEIPROC glad_glDisablei; -#define glDisablei glad_glDisablei -GLAD_API_CALL PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute; -#define glDispatchCompute glad_glDispatchCompute -GLAD_API_CALL PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect; -#define glDispatchComputeIndirect glad_glDispatchComputeIndirect -GLAD_API_CALL PFNGLDRAWARRAYSPROC glad_glDrawArrays; -#define glDrawArrays glad_glDrawArrays -GLAD_API_CALL PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect; -#define glDrawArraysIndirect glad_glDrawArraysIndirect -GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; -#define glDrawArraysInstanced glad_glDrawArraysInstanced -GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance; -#define glDrawArraysInstancedBaseInstance glad_glDrawArraysInstancedBaseInstance -GLAD_API_CALL PFNGLDRAWBUFFERPROC glad_glDrawBuffer; -#define glDrawBuffer glad_glDrawBuffer -GLAD_API_CALL PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; -#define glDrawBuffers glad_glDrawBuffers -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 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 PFNGLDRAWPIXELSPROC glad_glDrawPixels; -#define glDrawPixels glad_glDrawPixels -GLAD_API_CALL PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; -#define glDrawRangeElements glad_glDrawRangeElements -GLAD_API_CALL PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; -#define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex -GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback; -#define glDrawTransformFeedback glad_glDrawTransformFeedback -GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced; -#define glDrawTransformFeedbackInstanced glad_glDrawTransformFeedbackInstanced -GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream; -#define glDrawTransformFeedbackStream glad_glDrawTransformFeedbackStream -GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced; -#define glDrawTransformFeedbackStreamInstanced glad_glDrawTransformFeedbackStreamInstanced -GLAD_API_CALL PFNGLEDGEFLAGPROC glad_glEdgeFlag; -#define glEdgeFlag glad_glEdgeFlag -GLAD_API_CALL PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer; -#define glEdgeFlagPointer glad_glEdgeFlagPointer -GLAD_API_CALL PFNGLEDGEFLAGVPROC glad_glEdgeFlagv; -#define glEdgeFlagv glad_glEdgeFlagv -GLAD_API_CALL PFNGLENABLEPROC glad_glEnable; -#define glEnable glad_glEnable -GLAD_API_CALL PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState; -#define glEnableClientState glad_glEnableClientState -GLAD_API_CALL PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib; -#define glEnableVertexArrayAttrib glad_glEnableVertexArrayAttrib -GLAD_API_CALL PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; -#define glEnableVertexAttribArray glad_glEnableVertexAttribArray -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 PFNGLENDLISTPROC glad_glEndList; -#define glEndList glad_glEndList -GLAD_API_CALL PFNGLENDQUERYPROC glad_glEndQuery; -#define glEndQuery glad_glEndQuery -GLAD_API_CALL PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed; -#define glEndQueryIndexed glad_glEndQueryIndexed -GLAD_API_CALL PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; -#define glEndTransformFeedback glad_glEndTransformFeedback -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 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 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 PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer; -#define glFeedbackBuffer glad_glFeedbackBuffer -GLAD_API_CALL PFNGLFENCESYNCPROC glad_glFenceSync; -#define glFenceSync glad_glFenceSync -GLAD_API_CALL PFNGLFINISHPROC glad_glFinish; -#define glFinish glad_glFinish -GLAD_API_CALL PFNGLFLUSHPROC glad_glFlush; -#define glFlush glad_glFlush -GLAD_API_CALL PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; -#define glFlushMappedBufferRange glad_glFlushMappedBufferRange -GLAD_API_CALL PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange; -#define glFlushMappedNamedBufferRange glad_glFlushMappedNamedBufferRange -GLAD_API_CALL PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer; -#define glFogCoordPointer glad_glFogCoordPointer -GLAD_API_CALL PFNGLFOGCOORDDPROC glad_glFogCoordd; -#define glFogCoordd glad_glFogCoordd -GLAD_API_CALL PFNGLFOGCOORDDVPROC glad_glFogCoorddv; -#define glFogCoorddv glad_glFogCoorddv -GLAD_API_CALL PFNGLFOGCOORDFPROC glad_glFogCoordf; -#define glFogCoordf glad_glFogCoordf -GLAD_API_CALL PFNGLFOGCOORDFVPROC glad_glFogCoordfv; -#define glFogCoordfv glad_glFogCoordfv -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 PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri; -#define glFramebufferParameteri glad_glFramebufferParameteri -GLAD_API_CALL PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; -#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; -#define glFramebufferTexture glad_glFramebufferTexture -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; -#define glFramebufferTexture1D glad_glFramebufferTexture1D -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; -#define glFramebufferTexture2D glad_glFramebufferTexture2D -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; -#define glFramebufferTexture3D glad_glFramebufferTexture3D -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; -#define glFramebufferTextureLayer glad_glFramebufferTextureLayer -GLAD_API_CALL PFNGLFRONTFACEPROC glad_glFrontFace; -#define glFrontFace glad_glFrontFace -GLAD_API_CALL PFNGLFRUSTUMPROC glad_glFrustum; -#define glFrustum glad_glFrustum -GLAD_API_CALL PFNGLGENBUFFERSPROC glad_glGenBuffers; -#define glGenBuffers glad_glGenBuffers -GLAD_API_CALL PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; -#define glGenFramebuffers glad_glGenFramebuffers -GLAD_API_CALL PFNGLGENLISTSPROC glad_glGenLists; -#define glGenLists glad_glGenLists -GLAD_API_CALL PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines; -#define glGenProgramPipelines glad_glGenProgramPipelines -GLAD_API_CALL PFNGLGENQUERIESPROC glad_glGenQueries; -#define glGenQueries glad_glGenQueries -GLAD_API_CALL PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; -#define glGenRenderbuffers glad_glGenRenderbuffers -GLAD_API_CALL PFNGLGENSAMPLERSPROC glad_glGenSamplers; -#define glGenSamplers glad_glGenSamplers -GLAD_API_CALL PFNGLGENTEXTURESPROC glad_glGenTextures; -#define glGenTextures glad_glGenTextures -GLAD_API_CALL PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks; -#define glGenTransformFeedbacks glad_glGenTransformFeedbacks -GLAD_API_CALL PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; -#define glGenVertexArrays glad_glGenVertexArrays -GLAD_API_CALL PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; -#define glGenerateMipmap glad_glGenerateMipmap -GLAD_API_CALL PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap; -#define glGenerateTextureMipmap glad_glGenerateTextureMipmap -GLAD_API_CALL PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv; -#define glGetActiveAtomicCounterBufferiv glad_glGetActiveAtomicCounterBufferiv -GLAD_API_CALL PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; -#define glGetActiveAttrib glad_glGetActiveAttrib -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 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 PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; -#define glGetAttachedShaders glad_glGetAttachedShaders -GLAD_API_CALL PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; -#define glGetAttribLocation glad_glGetAttribLocation -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 PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; -#define glGetBufferPointerv glad_glGetBufferPointerv -GLAD_API_CALL PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; -#define glGetBufferSubData glad_glGetBufferSubData -GLAD_API_CALL PFNGLGETCLIPPLANEPROC glad_glGetClipPlane; -#define glGetClipPlane glad_glGetClipPlane -GLAD_API_CALL PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; -#define glGetCompressedTexImage glad_glGetCompressedTexImage -GLAD_API_CALL PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage; -#define glGetCompressedTextureImage glad_glGetCompressedTextureImage -GLAD_API_CALL PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage; -#define glGetCompressedTextureSubImage glad_glGetCompressedTextureSubImage -GLAD_API_CALL PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog; -#define glGetDebugMessageLog glad_glGetDebugMessageLog -GLAD_API_CALL PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v; -#define glGetDoublei_v glad_glGetDoublei_v -GLAD_API_CALL PFNGLGETDOUBLEVPROC glad_glGetDoublev; -#define glGetDoublev glad_glGetDoublev -GLAD_API_CALL PFNGLGETERRORPROC glad_glGetError; -#define glGetError glad_glGetError -GLAD_API_CALL PFNGLGETFLOATI_VPROC glad_glGetFloati_v; -#define glGetFloati_v glad_glGetFloati_v -GLAD_API_CALL PFNGLGETFLOATVPROC glad_glGetFloatv; -#define glGetFloatv glad_glGetFloatv -GLAD_API_CALL PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex; -#define glGetFragDataIndex glad_glGetFragDataIndex -GLAD_API_CALL PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; -#define glGetFragDataLocation glad_glGetFragDataLocation -GLAD_API_CALL PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; -#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv -GLAD_API_CALL PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv; -#define glGetFramebufferParameteriv glad_glGetFramebufferParameteriv -GLAD_API_CALL PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus; -#define glGetGraphicsResetStatus glad_glGetGraphicsResetStatus -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 PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; -#define glGetIntegeri_v glad_glGetIntegeri_v -GLAD_API_CALL PFNGLGETINTEGERVPROC glad_glGetIntegerv; -#define glGetIntegerv glad_glGetIntegerv -GLAD_API_CALL PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v; -#define glGetInternalformati64v glad_glGetInternalformati64v -GLAD_API_CALL PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ; -#define glGetInternalformativ glad_glGetInternalformativ -GLAD_API_CALL PFNGLGETLIGHTFVPROC glad_glGetLightfv; -#define glGetLightfv glad_glGetLightfv -GLAD_API_CALL PFNGLGETLIGHTIVPROC glad_glGetLightiv; -#define glGetLightiv glad_glGetLightiv -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 PFNGLGETMATERIALFVPROC glad_glGetMaterialfv; -#define glGetMaterialfv glad_glGetMaterialfv -GLAD_API_CALL PFNGLGETMATERIALIVPROC glad_glGetMaterialiv; -#define glGetMaterialiv glad_glGetMaterialiv -GLAD_API_CALL PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; -#define glGetMultisamplefv glad_glGetMultisamplefv -GLAD_API_CALL PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v; -#define glGetNamedBufferParameteri64v glad_glGetNamedBufferParameteri64v -GLAD_API_CALL PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv; -#define glGetNamedBufferParameteriv glad_glGetNamedBufferParameteriv -GLAD_API_CALL PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv; -#define glGetNamedBufferPointerv glad_glGetNamedBufferPointerv -GLAD_API_CALL PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData; -#define glGetNamedBufferSubData glad_glGetNamedBufferSubData -GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv; -#define glGetNamedFramebufferAttachmentParameteriv glad_glGetNamedFramebufferAttachmentParameteriv -GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv; -#define glGetNamedFramebufferParameteriv glad_glGetNamedFramebufferParameteriv -GLAD_API_CALL PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv; -#define glGetNamedRenderbufferParameteriv glad_glGetNamedRenderbufferParameteriv -GLAD_API_CALL PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel; -#define glGetObjectLabel glad_glGetObjectLabel -GLAD_API_CALL PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel; -#define glGetObjectPtrLabel glad_glGetObjectPtrLabel -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 PFNGLGETPOINTERVPROC glad_glGetPointerv; -#define glGetPointerv glad_glGetPointerv -GLAD_API_CALL PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple; -#define glGetPolygonStipple glad_glGetPolygonStipple -GLAD_API_CALL PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary; -#define glGetProgramBinary glad_glGetProgramBinary -GLAD_API_CALL PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; -#define glGetProgramInfoLog glad_glGetProgramInfoLog -GLAD_API_CALL PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv; -#define glGetProgramInterfaceiv glad_glGetProgramInterfaceiv -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 PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv; -#define glGetProgramResourceiv glad_glGetProgramResourceiv -GLAD_API_CALL PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv; -#define glGetProgramStageiv glad_glGetProgramStageiv -GLAD_API_CALL PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; -#define glGetProgramiv glad_glGetProgramiv -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 PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; -#define glGetQueryObjectiv glad_glGetQueryObjectiv -GLAD_API_CALL PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v; -#define glGetQueryObjectui64v glad_glGetQueryObjectui64v -GLAD_API_CALL PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; -#define glGetQueryObjectuiv glad_glGetQueryObjectuiv -GLAD_API_CALL PFNGLGETQUERYIVPROC glad_glGetQueryiv; -#define glGetQueryiv glad_glGetQueryiv -GLAD_API_CALL PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; -#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv -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 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 PFNGLGETSHADERIVPROC glad_glGetShaderiv; -#define glGetShaderiv glad_glGetShaderiv -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 PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv; -#define glGetTexEnvfv glad_glGetTexEnvfv -GLAD_API_CALL PFNGLGETTEXENVIVPROC glad_glGetTexEnviv; -#define glGetTexEnviv glad_glGetTexEnviv -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 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 PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; -#define glGetTexParameterIiv glad_glGetTexParameterIiv -GLAD_API_CALL PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; -#define glGetTexParameterIuiv glad_glGetTexParameterIuiv -GLAD_API_CALL PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; -#define glGetTexParameterfv glad_glGetTexParameterfv -GLAD_API_CALL PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; -#define glGetTexParameteriv glad_glGetTexParameteriv -GLAD_API_CALL PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage; -#define glGetTextureImage glad_glGetTextureImage -GLAD_API_CALL PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv; -#define glGetTextureLevelParameterfv glad_glGetTextureLevelParameterfv -GLAD_API_CALL PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv; -#define glGetTextureLevelParameteriv glad_glGetTextureLevelParameteriv -GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv; -#define glGetTextureParameterIiv glad_glGetTextureParameterIiv -GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv; -#define glGetTextureParameterIuiv glad_glGetTextureParameterIuiv -GLAD_API_CALL PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv; -#define glGetTextureParameterfv glad_glGetTextureParameterfv -GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv; -#define glGetTextureParameteriv glad_glGetTextureParameteriv -GLAD_API_CALL PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage; -#define glGetTextureSubImage glad_glGetTextureSubImage -GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; -#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying -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 PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; -#define glGetUniformIndices glad_glGetUniformIndices -GLAD_API_CALL PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; -#define glGetUniformLocation glad_glGetUniformLocation -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 PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; -#define glGetUniformiv glad_glGetUniformiv -GLAD_API_CALL PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; -#define glGetUniformuiv glad_glGetUniformuiv -GLAD_API_CALL PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv; -#define glGetVertexArrayIndexed64iv glad_glGetVertexArrayIndexed64iv -GLAD_API_CALL PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv; -#define glGetVertexArrayIndexediv glad_glGetVertexArrayIndexediv -GLAD_API_CALL PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv; -#define glGetVertexArrayiv glad_glGetVertexArrayiv -GLAD_API_CALL PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; -#define glGetVertexAttribIiv glad_glGetVertexAttribIiv -GLAD_API_CALL PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; -#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv -GLAD_API_CALL PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv; -#define glGetVertexAttribLdv glad_glGetVertexAttribLdv -GLAD_API_CALL PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; -#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv -GLAD_API_CALL PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; -#define glGetVertexAttribdv glad_glGetVertexAttribdv -GLAD_API_CALL PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; -#define glGetVertexAttribfv glad_glGetVertexAttribfv -GLAD_API_CALL PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; -#define glGetVertexAttribiv glad_glGetVertexAttribiv -GLAD_API_CALL PFNGLGETNCOLORTABLEPROC glad_glGetnColorTable; -#define glGetnColorTable glad_glGetnColorTable -GLAD_API_CALL PFNGLGETNCOMPRESSEDTEXIMAGEPROC glad_glGetnCompressedTexImage; -#define glGetnCompressedTexImage glad_glGetnCompressedTexImage -GLAD_API_CALL PFNGLGETNCONVOLUTIONFILTERPROC glad_glGetnConvolutionFilter; -#define glGetnConvolutionFilter glad_glGetnConvolutionFilter -GLAD_API_CALL PFNGLGETNHISTOGRAMPROC glad_glGetnHistogram; -#define glGetnHistogram glad_glGetnHistogram -GLAD_API_CALL PFNGLGETNMAPDVPROC glad_glGetnMapdv; -#define glGetnMapdv glad_glGetnMapdv -GLAD_API_CALL PFNGLGETNMAPFVPROC glad_glGetnMapfv; -#define glGetnMapfv glad_glGetnMapfv -GLAD_API_CALL PFNGLGETNMAPIVPROC glad_glGetnMapiv; -#define glGetnMapiv glad_glGetnMapiv -GLAD_API_CALL PFNGLGETNMINMAXPROC glad_glGetnMinmax; -#define glGetnMinmax glad_glGetnMinmax -GLAD_API_CALL PFNGLGETNPIXELMAPFVPROC glad_glGetnPixelMapfv; -#define glGetnPixelMapfv glad_glGetnPixelMapfv -GLAD_API_CALL PFNGLGETNPIXELMAPUIVPROC glad_glGetnPixelMapuiv; -#define glGetnPixelMapuiv glad_glGetnPixelMapuiv -GLAD_API_CALL PFNGLGETNPIXELMAPUSVPROC glad_glGetnPixelMapusv; -#define glGetnPixelMapusv glad_glGetnPixelMapusv -GLAD_API_CALL PFNGLGETNPOLYGONSTIPPLEPROC glad_glGetnPolygonStipple; -#define glGetnPolygonStipple glad_glGetnPolygonStipple -GLAD_API_CALL PFNGLGETNSEPARABLEFILTERPROC glad_glGetnSeparableFilter; -#define glGetnSeparableFilter glad_glGetnSeparableFilter -GLAD_API_CALL PFNGLGETNTEXIMAGEPROC glad_glGetnTexImage; -#define glGetnTexImage glad_glGetnTexImage -GLAD_API_CALL PFNGLGETNUNIFORMDVPROC glad_glGetnUniformdv; -#define glGetnUniformdv glad_glGetnUniformdv -GLAD_API_CALL PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv; -#define glGetnUniformfv glad_glGetnUniformfv -GLAD_API_CALL PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv; -#define glGetnUniformiv glad_glGetnUniformiv -GLAD_API_CALL PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv; -#define glGetnUniformuiv glad_glGetnUniformuiv -GLAD_API_CALL PFNGLHINTPROC glad_glHint; -#define glHint glad_glHint -GLAD_API_CALL PFNGLINDEXMASKPROC glad_glIndexMask; -#define glIndexMask glad_glIndexMask -GLAD_API_CALL PFNGLINDEXPOINTERPROC glad_glIndexPointer; -#define glIndexPointer glad_glIndexPointer -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 PFNGLINITNAMESPROC glad_glInitNames; -#define glInitNames glad_glInitNames -GLAD_API_CALL PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays; -#define glInterleavedArrays glad_glInterleavedArrays -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 PFNGLISBUFFERPROC glad_glIsBuffer; -#define glIsBuffer glad_glIsBuffer -GLAD_API_CALL PFNGLISENABLEDPROC glad_glIsEnabled; -#define glIsEnabled glad_glIsEnabled -GLAD_API_CALL PFNGLISENABLEDIPROC glad_glIsEnabledi; -#define glIsEnabledi glad_glIsEnabledi -GLAD_API_CALL PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; -#define glIsFramebuffer glad_glIsFramebuffer -GLAD_API_CALL PFNGLISLISTPROC glad_glIsList; -#define glIsList glad_glIsList -GLAD_API_CALL PFNGLISPROGRAMPROC glad_glIsProgram; -#define glIsProgram glad_glIsProgram -GLAD_API_CALL PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline; -#define glIsProgramPipeline glad_glIsProgramPipeline -GLAD_API_CALL PFNGLISQUERYPROC glad_glIsQuery; -#define glIsQuery glad_glIsQuery -GLAD_API_CALL PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; -#define glIsRenderbuffer glad_glIsRenderbuffer -GLAD_API_CALL PFNGLISSAMPLERPROC glad_glIsSampler; -#define glIsSampler glad_glIsSampler -GLAD_API_CALL PFNGLISSHADERPROC glad_glIsShader; -#define glIsShader glad_glIsShader -GLAD_API_CALL PFNGLISSYNCPROC glad_glIsSync; -#define glIsSync glad_glIsSync -GLAD_API_CALL PFNGLISTEXTUREPROC glad_glIsTexture; -#define glIsTexture glad_glIsTexture -GLAD_API_CALL PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback; -#define glIsTransformFeedback glad_glIsTransformFeedback -GLAD_API_CALL PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; -#define glIsVertexArray glad_glIsVertexArray -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 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 PFNGLLINESTIPPLEPROC glad_glLineStipple; -#define glLineStipple glad_glLineStipple -GLAD_API_CALL PFNGLLINEWIDTHPROC glad_glLineWidth; -#define glLineWidth glad_glLineWidth -GLAD_API_CALL PFNGLLINKPROGRAMPROC glad_glLinkProgram; -#define glLinkProgram glad_glLinkProgram -GLAD_API_CALL PFNGLLISTBASEPROC glad_glListBase; -#define glListBase glad_glListBase -GLAD_API_CALL PFNGLLOADIDENTITYPROC glad_glLoadIdentity; -#define glLoadIdentity glad_glLoadIdentity -GLAD_API_CALL PFNGLLOADMATRIXDPROC glad_glLoadMatrixd; -#define glLoadMatrixd glad_glLoadMatrixd -GLAD_API_CALL PFNGLLOADMATRIXFPROC glad_glLoadMatrixf; -#define glLoadMatrixf glad_glLoadMatrixf -GLAD_API_CALL PFNGLLOADNAMEPROC glad_glLoadName; -#define glLoadName glad_glLoadName -GLAD_API_CALL PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd; -#define glLoadTransposeMatrixd glad_glLoadTransposeMatrixd -GLAD_API_CALL PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf; -#define glLoadTransposeMatrixf glad_glLoadTransposeMatrixf -GLAD_API_CALL PFNGLLOGICOPPROC glad_glLogicOp; -#define glLogicOp glad_glLogicOp -GLAD_API_CALL PFNGLMAP1DPROC glad_glMap1d; -#define glMap1d glad_glMap1d -GLAD_API_CALL PFNGLMAP1FPROC glad_glMap1f; -#define glMap1f glad_glMap1f -GLAD_API_CALL PFNGLMAP2DPROC glad_glMap2d; -#define glMap2d glad_glMap2d -GLAD_API_CALL PFNGLMAP2FPROC glad_glMap2f; -#define glMap2f glad_glMap2f -GLAD_API_CALL PFNGLMAPBUFFERPROC glad_glMapBuffer; -#define glMapBuffer glad_glMapBuffer -GLAD_API_CALL PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; -#define glMapBufferRange glad_glMapBufferRange -GLAD_API_CALL PFNGLMAPGRID1DPROC glad_glMapGrid1d; -#define glMapGrid1d glad_glMapGrid1d -GLAD_API_CALL PFNGLMAPGRID1FPROC glad_glMapGrid1f; -#define glMapGrid1f glad_glMapGrid1f -GLAD_API_CALL PFNGLMAPGRID2DPROC glad_glMapGrid2d; -#define glMapGrid2d glad_glMapGrid2d -GLAD_API_CALL PFNGLMAPGRID2FPROC glad_glMapGrid2f; -#define glMapGrid2f glad_glMapGrid2f -GLAD_API_CALL PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer; -#define glMapNamedBuffer glad_glMapNamedBuffer -GLAD_API_CALL PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange; -#define glMapNamedBufferRange glad_glMapNamedBufferRange -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 PFNGLMATRIXMODEPROC glad_glMatrixMode; -#define glMatrixMode glad_glMatrixMode -GLAD_API_CALL PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier; -#define glMemoryBarrier glad_glMemoryBarrier -GLAD_API_CALL PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion; -#define glMemoryBarrierByRegion glad_glMemoryBarrierByRegion -GLAD_API_CALL PFNGLMINSAMPLESHADINGPROC glad_glMinSampleShading; -#define glMinSampleShading glad_glMinSampleShading -GLAD_API_CALL PFNGLMULTMATRIXDPROC glad_glMultMatrixd; -#define glMultMatrixd glad_glMultMatrixd -GLAD_API_CALL PFNGLMULTMATRIXFPROC glad_glMultMatrixf; -#define glMultMatrixf glad_glMultMatrixf -GLAD_API_CALL PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd; -#define glMultTransposeMatrixd glad_glMultTransposeMatrixd -GLAD_API_CALL PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf; -#define glMultTransposeMatrixf glad_glMultTransposeMatrixf -GLAD_API_CALL PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; -#define glMultiDrawArrays glad_glMultiDrawArrays -GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect; -#define glMultiDrawArraysIndirect glad_glMultiDrawArraysIndirect -GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC glad_glMultiDrawArraysIndirectCount; -#define glMultiDrawArraysIndirectCount glad_glMultiDrawArraysIndirectCount -GLAD_API_CALL PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; -#define glMultiDrawElements glad_glMultiDrawElements -GLAD_API_CALL PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; -#define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex -GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect; -#define glMultiDrawElementsIndirect glad_glMultiDrawElementsIndirect -GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC glad_glMultiDrawElementsIndirectCount; -#define glMultiDrawElementsIndirectCount glad_glMultiDrawElementsIndirectCount -GLAD_API_CALL PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d; -#define glMultiTexCoord1d glad_glMultiTexCoord1d -GLAD_API_CALL PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv; -#define glMultiTexCoord1dv glad_glMultiTexCoord1dv -GLAD_API_CALL PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f; -#define glMultiTexCoord1f glad_glMultiTexCoord1f -GLAD_API_CALL PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv; -#define glMultiTexCoord1fv glad_glMultiTexCoord1fv -GLAD_API_CALL PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i; -#define glMultiTexCoord1i glad_glMultiTexCoord1i -GLAD_API_CALL PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv; -#define glMultiTexCoord1iv glad_glMultiTexCoord1iv -GLAD_API_CALL PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s; -#define glMultiTexCoord1s glad_glMultiTexCoord1s -GLAD_API_CALL PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv; -#define glMultiTexCoord1sv glad_glMultiTexCoord1sv -GLAD_API_CALL PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d; -#define glMultiTexCoord2d glad_glMultiTexCoord2d -GLAD_API_CALL PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv; -#define glMultiTexCoord2dv glad_glMultiTexCoord2dv -GLAD_API_CALL PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f; -#define glMultiTexCoord2f glad_glMultiTexCoord2f -GLAD_API_CALL PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv; -#define glMultiTexCoord2fv glad_glMultiTexCoord2fv -GLAD_API_CALL PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i; -#define glMultiTexCoord2i glad_glMultiTexCoord2i -GLAD_API_CALL PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv; -#define glMultiTexCoord2iv glad_glMultiTexCoord2iv -GLAD_API_CALL PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s; -#define glMultiTexCoord2s glad_glMultiTexCoord2s -GLAD_API_CALL PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv; -#define glMultiTexCoord2sv glad_glMultiTexCoord2sv -GLAD_API_CALL PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d; -#define glMultiTexCoord3d glad_glMultiTexCoord3d -GLAD_API_CALL PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv; -#define glMultiTexCoord3dv glad_glMultiTexCoord3dv -GLAD_API_CALL PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f; -#define glMultiTexCoord3f glad_glMultiTexCoord3f -GLAD_API_CALL PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv; -#define glMultiTexCoord3fv glad_glMultiTexCoord3fv -GLAD_API_CALL PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i; -#define glMultiTexCoord3i glad_glMultiTexCoord3i -GLAD_API_CALL PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv; -#define glMultiTexCoord3iv glad_glMultiTexCoord3iv -GLAD_API_CALL PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s; -#define glMultiTexCoord3s glad_glMultiTexCoord3s -GLAD_API_CALL PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv; -#define glMultiTexCoord3sv glad_glMultiTexCoord3sv -GLAD_API_CALL PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d; -#define glMultiTexCoord4d glad_glMultiTexCoord4d -GLAD_API_CALL PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv; -#define glMultiTexCoord4dv glad_glMultiTexCoord4dv -GLAD_API_CALL PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f; -#define glMultiTexCoord4f glad_glMultiTexCoord4f -GLAD_API_CALL PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv; -#define glMultiTexCoord4fv glad_glMultiTexCoord4fv -GLAD_API_CALL PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i; -#define glMultiTexCoord4i glad_glMultiTexCoord4i -GLAD_API_CALL PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv; -#define glMultiTexCoord4iv glad_glMultiTexCoord4iv -GLAD_API_CALL PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s; -#define glMultiTexCoord4s glad_glMultiTexCoord4s -GLAD_API_CALL PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv; -#define glMultiTexCoord4sv glad_glMultiTexCoord4sv -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 PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData; -#define glNamedBufferData glad_glNamedBufferData -GLAD_API_CALL PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage; -#define glNamedBufferStorage glad_glNamedBufferStorage -GLAD_API_CALL PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData; -#define glNamedBufferSubData glad_glNamedBufferSubData -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 PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer; -#define glNamedFramebufferReadBuffer glad_glNamedFramebufferReadBuffer -GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer; -#define glNamedFramebufferRenderbuffer glad_glNamedFramebufferRenderbuffer -GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture; -#define glNamedFramebufferTexture glad_glNamedFramebufferTexture -GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer; -#define glNamedFramebufferTextureLayer glad_glNamedFramebufferTextureLayer -GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage; -#define glNamedRenderbufferStorage glad_glNamedRenderbufferStorage -GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample; -#define glNamedRenderbufferStorageMultisample glad_glNamedRenderbufferStorageMultisample -GLAD_API_CALL PFNGLNEWLISTPROC glad_glNewList; -#define glNewList glad_glNewList -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 PFNGLNORMAL3FVPROC glad_glNormal3fv; -#define glNormal3fv glad_glNormal3fv -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 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 PFNGLOBJECTLABELPROC glad_glObjectLabel; -#define glObjectLabel glad_glObjectLabel -GLAD_API_CALL PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel; -#define glObjectPtrLabel glad_glObjectPtrLabel -GLAD_API_CALL PFNGLORTHOPROC glad_glOrtho; -#define glOrtho glad_glOrtho -GLAD_API_CALL PFNGLPASSTHROUGHPROC glad_glPassThrough; -#define glPassThrough glad_glPassThrough -GLAD_API_CALL PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv; -#define glPatchParameterfv glad_glPatchParameterfv -GLAD_API_CALL PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri; -#define glPatchParameteri glad_glPatchParameteri -GLAD_API_CALL PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback; -#define glPauseTransformFeedback glad_glPauseTransformFeedback -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 PFNGLPIXELSTOREFPROC glad_glPixelStoref; -#define glPixelStoref glad_glPixelStoref -GLAD_API_CALL PFNGLPIXELSTOREIPROC glad_glPixelStorei; -#define glPixelStorei glad_glPixelStorei -GLAD_API_CALL PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf; -#define glPixelTransferf glad_glPixelTransferf -GLAD_API_CALL PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi; -#define glPixelTransferi glad_glPixelTransferi -GLAD_API_CALL PFNGLPIXELZOOMPROC glad_glPixelZoom; -#define glPixelZoom glad_glPixelZoom -GLAD_API_CALL PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; -#define glPointParameterf glad_glPointParameterf -GLAD_API_CALL PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; -#define glPointParameterfv glad_glPointParameterfv -GLAD_API_CALL PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; -#define glPointParameteri glad_glPointParameteri -GLAD_API_CALL PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; -#define glPointParameteriv glad_glPointParameteriv -GLAD_API_CALL PFNGLPOINTSIZEPROC glad_glPointSize; -#define glPointSize glad_glPointSize -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 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 PFNGLPOPMATRIXPROC glad_glPopMatrix; -#define glPopMatrix glad_glPopMatrix -GLAD_API_CALL PFNGLPOPNAMEPROC glad_glPopName; -#define glPopName glad_glPopName -GLAD_API_CALL PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; -#define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex -GLAD_API_CALL PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures; -#define glPrioritizeTextures glad_glPrioritizeTextures -GLAD_API_CALL PFNGLPROGRAMBINARYPROC glad_glProgramBinary; -#define glProgramBinary glad_glProgramBinary -GLAD_API_CALL PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri; -#define glProgramParameteri glad_glProgramParameteri -GLAD_API_CALL PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d; -#define glProgramUniform1d glad_glProgramUniform1d -GLAD_API_CALL PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv; -#define glProgramUniform1dv glad_glProgramUniform1dv -GLAD_API_CALL PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f; -#define glProgramUniform1f glad_glProgramUniform1f -GLAD_API_CALL PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv; -#define glProgramUniform1fv glad_glProgramUniform1fv -GLAD_API_CALL PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i; -#define glProgramUniform1i glad_glProgramUniform1i -GLAD_API_CALL PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv; -#define glProgramUniform1iv glad_glProgramUniform1iv -GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui; -#define glProgramUniform1ui glad_glProgramUniform1ui -GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv; -#define glProgramUniform1uiv glad_glProgramUniform1uiv -GLAD_API_CALL PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d; -#define glProgramUniform2d glad_glProgramUniform2d -GLAD_API_CALL PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv; -#define glProgramUniform2dv glad_glProgramUniform2dv -GLAD_API_CALL PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f; -#define glProgramUniform2f glad_glProgramUniform2f -GLAD_API_CALL PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv; -#define glProgramUniform2fv glad_glProgramUniform2fv -GLAD_API_CALL PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i; -#define glProgramUniform2i glad_glProgramUniform2i -GLAD_API_CALL PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv; -#define glProgramUniform2iv glad_glProgramUniform2iv -GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui; -#define glProgramUniform2ui glad_glProgramUniform2ui -GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv; -#define glProgramUniform2uiv glad_glProgramUniform2uiv -GLAD_API_CALL PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d; -#define glProgramUniform3d glad_glProgramUniform3d -GLAD_API_CALL PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv; -#define glProgramUniform3dv glad_glProgramUniform3dv -GLAD_API_CALL PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f; -#define glProgramUniform3f glad_glProgramUniform3f -GLAD_API_CALL PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv; -#define glProgramUniform3fv glad_glProgramUniform3fv -GLAD_API_CALL PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i; -#define glProgramUniform3i glad_glProgramUniform3i -GLAD_API_CALL PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv; -#define glProgramUniform3iv glad_glProgramUniform3iv -GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui; -#define glProgramUniform3ui glad_glProgramUniform3ui -GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv; -#define glProgramUniform3uiv glad_glProgramUniform3uiv -GLAD_API_CALL PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d; -#define glProgramUniform4d glad_glProgramUniform4d -GLAD_API_CALL PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv; -#define glProgramUniform4dv glad_glProgramUniform4dv -GLAD_API_CALL PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f; -#define glProgramUniform4f glad_glProgramUniform4f -GLAD_API_CALL PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv; -#define glProgramUniform4fv glad_glProgramUniform4fv -GLAD_API_CALL PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i; -#define glProgramUniform4i glad_glProgramUniform4i -GLAD_API_CALL PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv; -#define glProgramUniform4iv glad_glProgramUniform4iv -GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui; -#define glProgramUniform4ui glad_glProgramUniform4ui -GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv; -#define glProgramUniform4uiv glad_glProgramUniform4uiv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv; -#define glProgramUniformMatrix2dv glad_glProgramUniformMatrix2dv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv; -#define glProgramUniformMatrix2fv glad_glProgramUniformMatrix2fv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv; -#define glProgramUniformMatrix2x3dv glad_glProgramUniformMatrix2x3dv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv; -#define glProgramUniformMatrix2x3fv glad_glProgramUniformMatrix2x3fv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv; -#define glProgramUniformMatrix2x4dv glad_glProgramUniformMatrix2x4dv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv; -#define glProgramUniformMatrix2x4fv glad_glProgramUniformMatrix2x4fv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv; -#define glProgramUniformMatrix3dv glad_glProgramUniformMatrix3dv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv; -#define glProgramUniformMatrix3fv glad_glProgramUniformMatrix3fv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv; -#define glProgramUniformMatrix3x2dv glad_glProgramUniformMatrix3x2dv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv; -#define glProgramUniformMatrix3x2fv glad_glProgramUniformMatrix3x2fv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv; -#define glProgramUniformMatrix3x4dv glad_glProgramUniformMatrix3x4dv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv; -#define glProgramUniformMatrix3x4fv glad_glProgramUniformMatrix3x4fv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv; -#define glProgramUniformMatrix4dv glad_glProgramUniformMatrix4dv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv; -#define glProgramUniformMatrix4fv glad_glProgramUniformMatrix4fv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv; -#define glProgramUniformMatrix4x2dv glad_glProgramUniformMatrix4x2dv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv; -#define glProgramUniformMatrix4x2fv glad_glProgramUniformMatrix4x2fv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv; -#define glProgramUniformMatrix4x3dv glad_glProgramUniformMatrix4x3dv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv; -#define glProgramUniformMatrix4x3fv glad_glProgramUniformMatrix4x3fv -GLAD_API_CALL PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; -#define glProvokingVertex glad_glProvokingVertex -GLAD_API_CALL PFNGLPUSHATTRIBPROC glad_glPushAttrib; -#define glPushAttrib glad_glPushAttrib -GLAD_API_CALL PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib; -#define glPushClientAttrib glad_glPushClientAttrib -GLAD_API_CALL PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup; -#define glPushDebugGroup glad_glPushDebugGroup -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 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 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 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 PFNGLREADBUFFERPROC glad_glReadBuffer; -#define glReadBuffer glad_glReadBuffer -GLAD_API_CALL PFNGLREADPIXELSPROC glad_glReadPixels; -#define glReadPixels glad_glReadPixels -GLAD_API_CALL PFNGLREADNPIXELSPROC glad_glReadnPixels; -#define glReadnPixels glad_glReadnPixels -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 PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler; -#define glReleaseShaderCompiler glad_glReleaseShaderCompiler -GLAD_API_CALL PFNGLRENDERMODEPROC glad_glRenderMode; -#define glRenderMode glad_glRenderMode -GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; -#define glRenderbufferStorage glad_glRenderbufferStorage -GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; -#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample -GLAD_API_CALL PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback; -#define glResumeTransformFeedback glad_glResumeTransformFeedback -GLAD_API_CALL PFNGLROTATEDPROC glad_glRotated; -#define glRotated glad_glRotated -GLAD_API_CALL PFNGLROTATEFPROC glad_glRotatef; -#define glRotatef glad_glRotatef -GLAD_API_CALL PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; -#define glSampleCoverage glad_glSampleCoverage -GLAD_API_CALL PFNGLSAMPLEMASKIPROC glad_glSampleMaski; -#define glSampleMaski glad_glSampleMaski -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 PFNGLSCISSORPROC glad_glScissor; -#define glScissor glad_glScissor -GLAD_API_CALL PFNGLSCISSORARRAYVPROC glad_glScissorArrayv; -#define glScissorArrayv glad_glScissorArrayv -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 PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv; -#define glSecondaryColor3bv glad_glSecondaryColor3bv -GLAD_API_CALL PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d; -#define glSecondaryColor3d glad_glSecondaryColor3d -GLAD_API_CALL PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv; -#define glSecondaryColor3dv glad_glSecondaryColor3dv -GLAD_API_CALL PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f; -#define glSecondaryColor3f glad_glSecondaryColor3f -GLAD_API_CALL PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv; -#define glSecondaryColor3fv glad_glSecondaryColor3fv -GLAD_API_CALL PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i; -#define glSecondaryColor3i glad_glSecondaryColor3i -GLAD_API_CALL PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv; -#define glSecondaryColor3iv glad_glSecondaryColor3iv -GLAD_API_CALL PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s; -#define glSecondaryColor3s glad_glSecondaryColor3s -GLAD_API_CALL PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv; -#define glSecondaryColor3sv glad_glSecondaryColor3sv -GLAD_API_CALL PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub; -#define glSecondaryColor3ub glad_glSecondaryColor3ub -GLAD_API_CALL PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv; -#define glSecondaryColor3ubv glad_glSecondaryColor3ubv -GLAD_API_CALL PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui; -#define glSecondaryColor3ui glad_glSecondaryColor3ui -GLAD_API_CALL PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv; -#define glSecondaryColor3uiv glad_glSecondaryColor3uiv -GLAD_API_CALL PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us; -#define glSecondaryColor3us glad_glSecondaryColor3us -GLAD_API_CALL PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv; -#define glSecondaryColor3usv glad_glSecondaryColor3usv -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 PFNGLSELECTBUFFERPROC glad_glSelectBuffer; -#define glSelectBuffer glad_glSelectBuffer -GLAD_API_CALL PFNGLSHADEMODELPROC glad_glShadeModel; -#define glShadeModel glad_glShadeModel -GLAD_API_CALL PFNGLSHADERBINARYPROC glad_glShaderBinary; -#define glShaderBinary glad_glShaderBinary -GLAD_API_CALL PFNGLSHADERSOURCEPROC glad_glShaderSource; -#define glShaderSource glad_glShaderSource -GLAD_API_CALL PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding; -#define glShaderStorageBlockBinding glad_glShaderStorageBlockBinding -GLAD_API_CALL PFNGLSPECIALIZESHADERPROC glad_glSpecializeShader; -#define glSpecializeShader glad_glSpecializeShader -GLAD_API_CALL PFNGLSTENCILFUNCPROC glad_glStencilFunc; -#define glStencilFunc glad_glStencilFunc -GLAD_API_CALL PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; -#define glStencilFuncSeparate glad_glStencilFuncSeparate -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 PFNGLTEXBUFFERPROC glad_glTexBuffer; -#define glTexBuffer glad_glTexBuffer -GLAD_API_CALL PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange; -#define glTexBufferRange glad_glTexBufferRange -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 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 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 PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv; -#define glTexCoord2fv glad_glTexCoord2fv -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 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 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 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 PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv; -#define glTexCoord4fv glad_glTexCoord4fv -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 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 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 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 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 PFNGLTEXIMAGE3DPROC glad_glTexImage3D; -#define glTexImage3D glad_glTexImage3D -GLAD_API_CALL PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; -#define glTexImage3DMultisample glad_glTexImage3DMultisample -GLAD_API_CALL PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; -#define glTexParameterIiv glad_glTexParameterIiv -GLAD_API_CALL PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; -#define glTexParameterIuiv glad_glTexParameterIuiv -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 PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D; -#define glTexStorage1D glad_glTexStorage1D -GLAD_API_CALL PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D; -#define glTexStorage2D glad_glTexStorage2D -GLAD_API_CALL PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample; -#define glTexStorage2DMultisample glad_glTexStorage2DMultisample -GLAD_API_CALL PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D; -#define glTexStorage3D glad_glTexStorage3D -GLAD_API_CALL PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample; -#define glTexStorage3DMultisample glad_glTexStorage3DMultisample -GLAD_API_CALL PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; -#define glTexSubImage1D glad_glTexSubImage1D -GLAD_API_CALL PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; -#define glTexSubImage2D glad_glTexSubImage2D -GLAD_API_CALL PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; -#define glTexSubImage3D glad_glTexSubImage3D -GLAD_API_CALL PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier; -#define glTextureBarrier glad_glTextureBarrier -GLAD_API_CALL PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer; -#define glTextureBuffer glad_glTextureBuffer -GLAD_API_CALL PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange; -#define glTextureBufferRange glad_glTextureBufferRange -GLAD_API_CALL PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv; -#define glTextureParameterIiv glad_glTextureParameterIiv -GLAD_API_CALL PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv; -#define glTextureParameterIuiv glad_glTextureParameterIuiv -GLAD_API_CALL PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf; -#define glTextureParameterf glad_glTextureParameterf -GLAD_API_CALL PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv; -#define glTextureParameterfv glad_glTextureParameterfv -GLAD_API_CALL PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri; -#define glTextureParameteri glad_glTextureParameteri -GLAD_API_CALL PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv; -#define glTextureParameteriv glad_glTextureParameteriv -GLAD_API_CALL PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D; -#define glTextureStorage1D glad_glTextureStorage1D -GLAD_API_CALL PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D; -#define glTextureStorage2D glad_glTextureStorage2D -GLAD_API_CALL PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample; -#define glTextureStorage2DMultisample glad_glTextureStorage2DMultisample -GLAD_API_CALL PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D; -#define glTextureStorage3D glad_glTextureStorage3D -GLAD_API_CALL PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample; -#define glTextureStorage3DMultisample glad_glTextureStorage3DMultisample -GLAD_API_CALL PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D; -#define glTextureSubImage1D glad_glTextureSubImage1D -GLAD_API_CALL PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D; -#define glTextureSubImage2D glad_glTextureSubImage2D -GLAD_API_CALL PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D; -#define glTextureSubImage3D glad_glTextureSubImage3D -GLAD_API_CALL PFNGLTEXTUREVIEWPROC glad_glTextureView; -#define glTextureView glad_glTextureView -GLAD_API_CALL PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase; -#define glTransformFeedbackBufferBase glad_glTransformFeedbackBufferBase -GLAD_API_CALL PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange; -#define glTransformFeedbackBufferRange glad_glTransformFeedbackBufferRange -GLAD_API_CALL PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; -#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings -GLAD_API_CALL PFNGLTRANSLATEDPROC glad_glTranslated; -#define glTranslated glad_glTranslated -GLAD_API_CALL PFNGLTRANSLATEFPROC glad_glTranslatef; -#define glTranslatef glad_glTranslatef -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 PFNGLUNIFORM1FVPROC glad_glUniform1fv; -#define glUniform1fv glad_glUniform1fv -GLAD_API_CALL PFNGLUNIFORM1IPROC glad_glUniform1i; -#define glUniform1i glad_glUniform1i -GLAD_API_CALL PFNGLUNIFORM1IVPROC glad_glUniform1iv; -#define glUniform1iv glad_glUniform1iv -GLAD_API_CALL PFNGLUNIFORM1UIPROC glad_glUniform1ui; -#define glUniform1ui glad_glUniform1ui -GLAD_API_CALL PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; -#define glUniform1uiv glad_glUniform1uiv -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 PFNGLUNIFORM2FVPROC glad_glUniform2fv; -#define glUniform2fv glad_glUniform2fv -GLAD_API_CALL PFNGLUNIFORM2IPROC glad_glUniform2i; -#define glUniform2i glad_glUniform2i -GLAD_API_CALL PFNGLUNIFORM2IVPROC glad_glUniform2iv; -#define glUniform2iv glad_glUniform2iv -GLAD_API_CALL PFNGLUNIFORM2UIPROC glad_glUniform2ui; -#define glUniform2ui glad_glUniform2ui -GLAD_API_CALL PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; -#define glUniform2uiv glad_glUniform2uiv -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 PFNGLUNIFORM3FVPROC glad_glUniform3fv; -#define glUniform3fv glad_glUniform3fv -GLAD_API_CALL PFNGLUNIFORM3IPROC glad_glUniform3i; -#define glUniform3i glad_glUniform3i -GLAD_API_CALL PFNGLUNIFORM3IVPROC glad_glUniform3iv; -#define glUniform3iv glad_glUniform3iv -GLAD_API_CALL PFNGLUNIFORM3UIPROC glad_glUniform3ui; -#define glUniform3ui glad_glUniform3ui -GLAD_API_CALL PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; -#define glUniform3uiv glad_glUniform3uiv -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 PFNGLUNIFORM4FVPROC glad_glUniform4fv; -#define glUniform4fv glad_glUniform4fv -GLAD_API_CALL PFNGLUNIFORM4IPROC glad_glUniform4i; -#define glUniform4i glad_glUniform4i -GLAD_API_CALL PFNGLUNIFORM4IVPROC glad_glUniform4iv; -#define glUniform4iv glad_glUniform4iv -GLAD_API_CALL PFNGLUNIFORM4UIPROC glad_glUniform4ui; -#define glUniform4ui glad_glUniform4ui -GLAD_API_CALL PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; -#define glUniform4uiv glad_glUniform4uiv -GLAD_API_CALL PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; -#define glUniformBlockBinding glad_glUniformBlockBinding -GLAD_API_CALL PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv; -#define glUniformMatrix2dv glad_glUniformMatrix2dv -GLAD_API_CALL PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; -#define glUniformMatrix2fv glad_glUniformMatrix2fv -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 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 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 PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; -#define glUnmapBuffer glad_glUnmapBuffer -GLAD_API_CALL PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer; -#define glUnmapNamedBuffer glad_glUnmapNamedBuffer -GLAD_API_CALL PFNGLUSEPROGRAMPROC glad_glUseProgram; -#define glUseProgram glad_glUseProgram -GLAD_API_CALL PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages; -#define glUseProgramStages glad_glUseProgramStages -GLAD_API_CALL PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; -#define glValidateProgram glad_glValidateProgram -GLAD_API_CALL PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline; -#define glValidateProgramPipeline glad_glValidateProgramPipeline -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 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 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 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 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 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 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 PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor; -#define glVertexArrayBindingDivisor glad_glVertexArrayBindingDivisor -GLAD_API_CALL PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer; -#define glVertexArrayElementBuffer glad_glVertexArrayElementBuffer -GLAD_API_CALL PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer; -#define glVertexArrayVertexBuffer glad_glVertexArrayVertexBuffer -GLAD_API_CALL PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers; -#define glVertexArrayVertexBuffers glad_glVertexArrayVertexBuffers -GLAD_API_CALL PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; -#define glVertexAttrib1d glad_glVertexAttrib1d -GLAD_API_CALL PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; -#define glVertexAttrib1dv glad_glVertexAttrib1dv -GLAD_API_CALL PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; -#define glVertexAttrib1f glad_glVertexAttrib1f -GLAD_API_CALL PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; -#define glVertexAttrib1fv glad_glVertexAttrib1fv -GLAD_API_CALL PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; -#define glVertexAttrib1s glad_glVertexAttrib1s -GLAD_API_CALL PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; -#define glVertexAttrib1sv glad_glVertexAttrib1sv -GLAD_API_CALL PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; -#define glVertexAttrib2d glad_glVertexAttrib2d -GLAD_API_CALL PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; -#define glVertexAttrib2dv glad_glVertexAttrib2dv -GLAD_API_CALL PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; -#define glVertexAttrib2f glad_glVertexAttrib2f -GLAD_API_CALL PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; -#define glVertexAttrib2fv glad_glVertexAttrib2fv -GLAD_API_CALL PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; -#define glVertexAttrib2s glad_glVertexAttrib2s -GLAD_API_CALL PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; -#define glVertexAttrib2sv glad_glVertexAttrib2sv -GLAD_API_CALL PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; -#define glVertexAttrib3d glad_glVertexAttrib3d -GLAD_API_CALL PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; -#define glVertexAttrib3dv glad_glVertexAttrib3dv -GLAD_API_CALL PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; -#define glVertexAttrib3f glad_glVertexAttrib3f -GLAD_API_CALL PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; -#define glVertexAttrib3fv glad_glVertexAttrib3fv -GLAD_API_CALL PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; -#define glVertexAttrib3s glad_glVertexAttrib3s -GLAD_API_CALL PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; -#define glVertexAttrib3sv glad_glVertexAttrib3sv -GLAD_API_CALL PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; -#define glVertexAttrib4Nbv glad_glVertexAttrib4Nbv -GLAD_API_CALL PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; -#define glVertexAttrib4Niv glad_glVertexAttrib4Niv -GLAD_API_CALL PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; -#define glVertexAttrib4Nsv glad_glVertexAttrib4Nsv -GLAD_API_CALL PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; -#define glVertexAttrib4Nub glad_glVertexAttrib4Nub -GLAD_API_CALL PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; -#define glVertexAttrib4Nubv glad_glVertexAttrib4Nubv -GLAD_API_CALL PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; -#define glVertexAttrib4Nuiv glad_glVertexAttrib4Nuiv -GLAD_API_CALL PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; -#define glVertexAttrib4Nusv glad_glVertexAttrib4Nusv -GLAD_API_CALL PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; -#define glVertexAttrib4bv glad_glVertexAttrib4bv -GLAD_API_CALL PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; -#define glVertexAttrib4d glad_glVertexAttrib4d -GLAD_API_CALL PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; -#define glVertexAttrib4dv glad_glVertexAttrib4dv -GLAD_API_CALL PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; -#define glVertexAttrib4f glad_glVertexAttrib4f -GLAD_API_CALL PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; -#define glVertexAttrib4fv glad_glVertexAttrib4fv -GLAD_API_CALL PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; -#define glVertexAttrib4iv glad_glVertexAttrib4iv -GLAD_API_CALL PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; -#define glVertexAttrib4s glad_glVertexAttrib4s -GLAD_API_CALL PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; -#define glVertexAttrib4sv glad_glVertexAttrib4sv -GLAD_API_CALL PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; -#define glVertexAttrib4ubv glad_glVertexAttrib4ubv -GLAD_API_CALL PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; -#define glVertexAttrib4uiv glad_glVertexAttrib4uiv -GLAD_API_CALL PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; -#define glVertexAttrib4usv glad_glVertexAttrib4usv -GLAD_API_CALL PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding; -#define glVertexAttribBinding glad_glVertexAttribBinding -GLAD_API_CALL PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; -#define glVertexAttribDivisor glad_glVertexAttribDivisor -GLAD_API_CALL PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat; -#define glVertexAttribFormat glad_glVertexAttribFormat -GLAD_API_CALL PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; -#define glVertexAttribI1i glad_glVertexAttribI1i -GLAD_API_CALL PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; -#define glVertexAttribI1iv glad_glVertexAttribI1iv -GLAD_API_CALL PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; -#define glVertexAttribI1ui glad_glVertexAttribI1ui -GLAD_API_CALL PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; -#define glVertexAttribI1uiv glad_glVertexAttribI1uiv -GLAD_API_CALL PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; -#define glVertexAttribI2i glad_glVertexAttribI2i -GLAD_API_CALL PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; -#define glVertexAttribI2iv glad_glVertexAttribI2iv -GLAD_API_CALL PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; -#define glVertexAttribI2ui glad_glVertexAttribI2ui -GLAD_API_CALL PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; -#define glVertexAttribI2uiv glad_glVertexAttribI2uiv -GLAD_API_CALL PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; -#define glVertexAttribI3i glad_glVertexAttribI3i -GLAD_API_CALL PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; -#define glVertexAttribI3iv glad_glVertexAttribI3iv -GLAD_API_CALL PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; -#define glVertexAttribI3ui glad_glVertexAttribI3ui -GLAD_API_CALL PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; -#define glVertexAttribI3uiv glad_glVertexAttribI3uiv -GLAD_API_CALL PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; -#define glVertexAttribI4bv glad_glVertexAttribI4bv -GLAD_API_CALL PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; -#define glVertexAttribI4i glad_glVertexAttribI4i -GLAD_API_CALL PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; -#define glVertexAttribI4iv glad_glVertexAttribI4iv -GLAD_API_CALL PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; -#define glVertexAttribI4sv glad_glVertexAttribI4sv -GLAD_API_CALL PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; -#define glVertexAttribI4ubv glad_glVertexAttribI4ubv -GLAD_API_CALL PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; -#define glVertexAttribI4ui glad_glVertexAttribI4ui -GLAD_API_CALL PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; -#define glVertexAttribI4uiv glad_glVertexAttribI4uiv -GLAD_API_CALL PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; -#define glVertexAttribI4usv glad_glVertexAttribI4usv -GLAD_API_CALL PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat; -#define glVertexAttribIFormat glad_glVertexAttribIFormat -GLAD_API_CALL PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; -#define glVertexAttribIPointer glad_glVertexAttribIPointer -GLAD_API_CALL PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d; -#define glVertexAttribL1d glad_glVertexAttribL1d -GLAD_API_CALL PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv; -#define glVertexAttribL1dv glad_glVertexAttribL1dv -GLAD_API_CALL PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d; -#define glVertexAttribL2d glad_glVertexAttribL2d -GLAD_API_CALL PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv; -#define glVertexAttribL2dv glad_glVertexAttribL2dv -GLAD_API_CALL PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d; -#define glVertexAttribL3d glad_glVertexAttribL3d -GLAD_API_CALL PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv; -#define glVertexAttribL3dv glad_glVertexAttribL3dv -GLAD_API_CALL PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d; -#define glVertexAttribL4d glad_glVertexAttribL4d -GLAD_API_CALL PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv; -#define glVertexAttribL4dv glad_glVertexAttribL4dv -GLAD_API_CALL PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat; -#define glVertexAttribLFormat glad_glVertexAttribLFormat -GLAD_API_CALL PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer; -#define glVertexAttribLPointer glad_glVertexAttribLPointer -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 PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; -#define glVertexAttribPointer glad_glVertexAttribPointer -GLAD_API_CALL PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor; -#define glVertexBindingDivisor glad_glVertexBindingDivisor -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 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 PFNGLWAITSYNCPROC glad_glWaitSync; -#define glWaitSync glad_glWaitSync -GLAD_API_CALL PFNGLWINDOWPOS2DPROC glad_glWindowPos2d; -#define glWindowPos2d glad_glWindowPos2d -GLAD_API_CALL PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv; -#define glWindowPos2dv glad_glWindowPos2dv -GLAD_API_CALL PFNGLWINDOWPOS2FPROC glad_glWindowPos2f; -#define glWindowPos2f glad_glWindowPos2f -GLAD_API_CALL PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv; -#define glWindowPos2fv glad_glWindowPos2fv -GLAD_API_CALL PFNGLWINDOWPOS2IPROC glad_glWindowPos2i; -#define glWindowPos2i glad_glWindowPos2i -GLAD_API_CALL PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv; -#define glWindowPos2iv glad_glWindowPos2iv -GLAD_API_CALL PFNGLWINDOWPOS2SPROC glad_glWindowPos2s; -#define glWindowPos2s glad_glWindowPos2s -GLAD_API_CALL PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv; -#define glWindowPos2sv glad_glWindowPos2sv -GLAD_API_CALL PFNGLWINDOWPOS3DPROC glad_glWindowPos3d; -#define glWindowPos3d glad_glWindowPos3d -GLAD_API_CALL PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv; -#define glWindowPos3dv glad_glWindowPos3dv -GLAD_API_CALL PFNGLWINDOWPOS3FPROC glad_glWindowPos3f; -#define glWindowPos3f glad_glWindowPos3f -GLAD_API_CALL PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv; -#define glWindowPos3fv glad_glWindowPos3fv -GLAD_API_CALL PFNGLWINDOWPOS3IPROC glad_glWindowPos3i; -#define glWindowPos3i glad_glWindowPos3i -GLAD_API_CALL PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv; -#define glWindowPos3iv glad_glWindowPos3iv -GLAD_API_CALL PFNGLWINDOWPOS3SPROC glad_glWindowPos3s; -#define glWindowPos3s glad_glWindowPos3s -GLAD_API_CALL PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv; -#define glWindowPos3sv glad_glWindowPos3sv +typedef struct GladGLContext { + void* userptr; + int VERSION_1_0; + int VERSION_1_1; + int VERSION_1_2; + int VERSION_1_3; + int VERSION_1_4; + int VERSION_1_5; + int VERSION_2_0; + int VERSION_2_1; + int VERSION_3_0; + int VERSION_3_1; + int VERSION_3_2; + int VERSION_3_3; + int VERSION_4_0; + int VERSION_4_1; + int VERSION_4_2; + int VERSION_4_3; + int VERSION_4_4; + int VERSION_4_5; + int VERSION_4_6; + PFNGLACCUMPROC Accum; + PFNGLACTIVESHADERPROGRAMPROC ActiveShaderProgram; + PFNGLACTIVETEXTUREPROC ActiveTexture; + PFNGLALPHAFUNCPROC AlphaFunc; + PFNGLARETEXTURESRESIDENTPROC AreTexturesResident; + PFNGLARRAYELEMENTPROC ArrayElement; + PFNGLATTACHSHADERPROC AttachShader; + PFNGLBEGINPROC Begin; + PFNGLBEGINCONDITIONALRENDERPROC BeginConditionalRender; + PFNGLBEGINQUERYPROC BeginQuery; + PFNGLBEGINQUERYINDEXEDPROC BeginQueryIndexed; + PFNGLBEGINTRANSFORMFEEDBACKPROC BeginTransformFeedback; + PFNGLBINDATTRIBLOCATIONPROC BindAttribLocation; + PFNGLBINDBUFFERPROC BindBuffer; + PFNGLBINDBUFFERBASEPROC BindBufferBase; + PFNGLBINDBUFFERRANGEPROC BindBufferRange; + PFNGLBINDBUFFERSBASEPROC BindBuffersBase; + PFNGLBINDBUFFERSRANGEPROC BindBuffersRange; + PFNGLBINDFRAGDATALOCATIONPROC BindFragDataLocation; + PFNGLBINDFRAGDATALOCATIONINDEXEDPROC BindFragDataLocationIndexed; + PFNGLBINDFRAMEBUFFERPROC BindFramebuffer; + PFNGLBINDIMAGETEXTUREPROC BindImageTexture; + PFNGLBINDIMAGETEXTURESPROC BindImageTextures; + PFNGLBINDPROGRAMPIPELINEPROC BindProgramPipeline; + PFNGLBINDRENDERBUFFERPROC BindRenderbuffer; + PFNGLBINDSAMPLERPROC BindSampler; + PFNGLBINDSAMPLERSPROC BindSamplers; + PFNGLBINDTEXTUREPROC BindTexture; + PFNGLBINDTEXTUREUNITPROC BindTextureUnit; + PFNGLBINDTEXTURESPROC BindTextures; + PFNGLBINDTRANSFORMFEEDBACKPROC BindTransformFeedback; + PFNGLBINDVERTEXARRAYPROC BindVertexArray; + PFNGLBINDVERTEXBUFFERPROC BindVertexBuffer; + PFNGLBINDVERTEXBUFFERSPROC BindVertexBuffers; + PFNGLBITMAPPROC Bitmap; + PFNGLBLENDCOLORPROC BlendColor; + PFNGLBLENDEQUATIONPROC BlendEquation; + PFNGLBLENDEQUATIONSEPARATEPROC BlendEquationSeparate; + PFNGLBLENDEQUATIONSEPARATEIPROC BlendEquationSeparatei; + PFNGLBLENDEQUATIONIPROC BlendEquationi; + PFNGLBLENDFUNCPROC BlendFunc; + PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate; + PFNGLBLENDFUNCSEPARATEIPROC BlendFuncSeparatei; + PFNGLBLENDFUNCIPROC BlendFunci; + PFNGLBLITFRAMEBUFFERPROC BlitFramebuffer; + PFNGLBLITNAMEDFRAMEBUFFERPROC BlitNamedFramebuffer; + PFNGLBUFFERDATAPROC BufferData; + PFNGLBUFFERSTORAGEPROC BufferStorage; + PFNGLBUFFERSUBDATAPROC BufferSubData; + PFNGLCALLLISTPROC CallList; + PFNGLCALLLISTSPROC CallLists; + PFNGLCHECKFRAMEBUFFERSTATUSPROC CheckFramebufferStatus; + PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC CheckNamedFramebufferStatus; + PFNGLCLAMPCOLORPROC ClampColor; + PFNGLCLEARPROC Clear; + PFNGLCLEARACCUMPROC ClearAccum; + PFNGLCLEARBUFFERDATAPROC ClearBufferData; + PFNGLCLEARBUFFERSUBDATAPROC ClearBufferSubData; + PFNGLCLEARBUFFERFIPROC ClearBufferfi; + PFNGLCLEARBUFFERFVPROC ClearBufferfv; + PFNGLCLEARBUFFERIVPROC ClearBufferiv; + PFNGLCLEARBUFFERUIVPROC ClearBufferuiv; + PFNGLCLEARCOLORPROC ClearColor; + PFNGLCLEARDEPTHPROC ClearDepth; + PFNGLCLEARDEPTHFPROC ClearDepthf; + PFNGLCLEARINDEXPROC ClearIndex; + PFNGLCLEARNAMEDBUFFERDATAPROC ClearNamedBufferData; + PFNGLCLEARNAMEDBUFFERSUBDATAPROC ClearNamedBufferSubData; + PFNGLCLEARNAMEDFRAMEBUFFERFIPROC ClearNamedFramebufferfi; + PFNGLCLEARNAMEDFRAMEBUFFERFVPROC ClearNamedFramebufferfv; + PFNGLCLEARNAMEDFRAMEBUFFERIVPROC ClearNamedFramebufferiv; + PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC ClearNamedFramebufferuiv; + PFNGLCLEARSTENCILPROC ClearStencil; + PFNGLCLEARTEXIMAGEPROC ClearTexImage; + PFNGLCLEARTEXSUBIMAGEPROC ClearTexSubImage; + PFNGLCLIENTACTIVETEXTUREPROC ClientActiveTexture; + PFNGLCLIENTWAITSYNCPROC ClientWaitSync; + PFNGLCLIPCONTROLPROC ClipControl; + PFNGLCLIPPLANEPROC ClipPlane; + PFNGLCOLOR3BPROC Color3b; + PFNGLCOLOR3BVPROC Color3bv; + PFNGLCOLOR3DPROC Color3d; + PFNGLCOLOR3DVPROC Color3dv; + PFNGLCOLOR3FPROC Color3f; + PFNGLCOLOR3FVPROC Color3fv; + PFNGLCOLOR3IPROC Color3i; + PFNGLCOLOR3IVPROC Color3iv; + PFNGLCOLOR3SPROC Color3s; + PFNGLCOLOR3SVPROC Color3sv; + PFNGLCOLOR3UBPROC Color3ub; + PFNGLCOLOR3UBVPROC Color3ubv; + PFNGLCOLOR3UIPROC Color3ui; + PFNGLCOLOR3UIVPROC Color3uiv; + PFNGLCOLOR3USPROC Color3us; + PFNGLCOLOR3USVPROC Color3usv; + PFNGLCOLOR4BPROC Color4b; + PFNGLCOLOR4BVPROC Color4bv; + PFNGLCOLOR4DPROC Color4d; + PFNGLCOLOR4DVPROC Color4dv; + PFNGLCOLOR4FPROC Color4f; + PFNGLCOLOR4FVPROC Color4fv; + PFNGLCOLOR4IPROC Color4i; + PFNGLCOLOR4IVPROC Color4iv; + PFNGLCOLOR4SPROC Color4s; + PFNGLCOLOR4SVPROC Color4sv; + PFNGLCOLOR4UBPROC Color4ub; + PFNGLCOLOR4UBVPROC Color4ubv; + PFNGLCOLOR4UIPROC Color4ui; + PFNGLCOLOR4UIVPROC Color4uiv; + PFNGLCOLOR4USPROC Color4us; + PFNGLCOLOR4USVPROC Color4usv; + PFNGLCOLORMASKPROC ColorMask; + PFNGLCOLORMASKIPROC ColorMaski; + PFNGLCOLORMATERIALPROC ColorMaterial; + PFNGLCOLORP3UIPROC ColorP3ui; + PFNGLCOLORP3UIVPROC ColorP3uiv; + PFNGLCOLORP4UIPROC ColorP4ui; + PFNGLCOLORP4UIVPROC ColorP4uiv; + PFNGLCOLORPOINTERPROC ColorPointer; + PFNGLCOMPILESHADERPROC CompileShader; + PFNGLCOMPRESSEDTEXIMAGE1DPROC CompressedTexImage1D; + PFNGLCOMPRESSEDTEXIMAGE2DPROC CompressedTexImage2D; + PFNGLCOMPRESSEDTEXIMAGE3DPROC CompressedTexImage3D; + PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC CompressedTexSubImage1D; + PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC CompressedTexSubImage2D; + PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC CompressedTexSubImage3D; + PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC CompressedTextureSubImage1D; + PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC CompressedTextureSubImage2D; + PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC CompressedTextureSubImage3D; + PFNGLCOPYBUFFERSUBDATAPROC CopyBufferSubData; + PFNGLCOPYIMAGESUBDATAPROC CopyImageSubData; + PFNGLCOPYNAMEDBUFFERSUBDATAPROC CopyNamedBufferSubData; + PFNGLCOPYPIXELSPROC CopyPixels; + PFNGLCOPYTEXIMAGE1DPROC CopyTexImage1D; + PFNGLCOPYTEXIMAGE2DPROC CopyTexImage2D; + PFNGLCOPYTEXSUBIMAGE1DPROC CopyTexSubImage1D; + PFNGLCOPYTEXSUBIMAGE2DPROC CopyTexSubImage2D; + PFNGLCOPYTEXSUBIMAGE3DPROC CopyTexSubImage3D; + PFNGLCOPYTEXTURESUBIMAGE1DPROC CopyTextureSubImage1D; + PFNGLCOPYTEXTURESUBIMAGE2DPROC CopyTextureSubImage2D; + PFNGLCOPYTEXTURESUBIMAGE3DPROC CopyTextureSubImage3D; + PFNGLCREATEBUFFERSPROC CreateBuffers; + PFNGLCREATEFRAMEBUFFERSPROC CreateFramebuffers; + PFNGLCREATEPROGRAMPROC CreateProgram; + PFNGLCREATEPROGRAMPIPELINESPROC CreateProgramPipelines; + PFNGLCREATEQUERIESPROC CreateQueries; + PFNGLCREATERENDERBUFFERSPROC CreateRenderbuffers; + PFNGLCREATESAMPLERSPROC CreateSamplers; + PFNGLCREATESHADERPROC CreateShader; + PFNGLCREATESHADERPROGRAMVPROC CreateShaderProgramv; + PFNGLCREATETEXTURESPROC CreateTextures; + PFNGLCREATETRANSFORMFEEDBACKSPROC CreateTransformFeedbacks; + PFNGLCREATEVERTEXARRAYSPROC CreateVertexArrays; + PFNGLCULLFACEPROC CullFace; + PFNGLDEBUGMESSAGECALLBACKPROC DebugMessageCallback; + PFNGLDEBUGMESSAGECONTROLPROC DebugMessageControl; + PFNGLDEBUGMESSAGEINSERTPROC DebugMessageInsert; + PFNGLDELETEBUFFERSPROC DeleteBuffers; + PFNGLDELETEFRAMEBUFFERSPROC DeleteFramebuffers; + PFNGLDELETELISTSPROC DeleteLists; + PFNGLDELETEPROGRAMPROC DeleteProgram; + PFNGLDELETEPROGRAMPIPELINESPROC DeleteProgramPipelines; + PFNGLDELETEQUERIESPROC DeleteQueries; + PFNGLDELETERENDERBUFFERSPROC DeleteRenderbuffers; + PFNGLDELETESAMPLERSPROC DeleteSamplers; + PFNGLDELETESHADERPROC DeleteShader; + PFNGLDELETESYNCPROC DeleteSync; + PFNGLDELETETEXTURESPROC DeleteTextures; + PFNGLDELETETRANSFORMFEEDBACKSPROC DeleteTransformFeedbacks; + PFNGLDELETEVERTEXARRAYSPROC DeleteVertexArrays; + PFNGLDEPTHFUNCPROC DepthFunc; + PFNGLDEPTHMASKPROC DepthMask; + PFNGLDEPTHRANGEPROC DepthRange; + PFNGLDEPTHRANGEARRAYVPROC DepthRangeArrayv; + PFNGLDEPTHRANGEINDEXEDPROC DepthRangeIndexed; + PFNGLDEPTHRANGEFPROC DepthRangef; + PFNGLDETACHSHADERPROC DetachShader; + PFNGLDISABLEPROC Disable; + PFNGLDISABLECLIENTSTATEPROC DisableClientState; + PFNGLDISABLEVERTEXARRAYATTRIBPROC DisableVertexArrayAttrib; + PFNGLDISABLEVERTEXATTRIBARRAYPROC DisableVertexAttribArray; + PFNGLDISABLEIPROC Disablei; + PFNGLDISPATCHCOMPUTEPROC DispatchCompute; + PFNGLDISPATCHCOMPUTEINDIRECTPROC DispatchComputeIndirect; + PFNGLDRAWARRAYSPROC DrawArrays; + PFNGLDRAWARRAYSINDIRECTPROC DrawArraysIndirect; + PFNGLDRAWARRAYSINSTANCEDPROC DrawArraysInstanced; + PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC DrawArraysInstancedBaseInstance; + PFNGLDRAWBUFFERPROC DrawBuffer; + PFNGLDRAWBUFFERSPROC DrawBuffers; + PFNGLDRAWELEMENTSPROC DrawElements; + PFNGLDRAWELEMENTSBASEVERTEXPROC DrawElementsBaseVertex; + PFNGLDRAWELEMENTSINDIRECTPROC DrawElementsIndirect; + PFNGLDRAWELEMENTSINSTANCEDPROC DrawElementsInstanced; + PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC DrawElementsInstancedBaseInstance; + PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC DrawElementsInstancedBaseVertex; + PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC DrawElementsInstancedBaseVertexBaseInstance; + PFNGLDRAWPIXELSPROC DrawPixels; + PFNGLDRAWRANGEELEMENTSPROC DrawRangeElements; + PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC DrawRangeElementsBaseVertex; + PFNGLDRAWTRANSFORMFEEDBACKPROC DrawTransformFeedback; + PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC DrawTransformFeedbackInstanced; + PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC DrawTransformFeedbackStream; + PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC DrawTransformFeedbackStreamInstanced; + PFNGLEDGEFLAGPROC EdgeFlag; + PFNGLEDGEFLAGPOINTERPROC EdgeFlagPointer; + PFNGLEDGEFLAGVPROC EdgeFlagv; + PFNGLENABLEPROC Enable; + PFNGLENABLECLIENTSTATEPROC EnableClientState; + PFNGLENABLEVERTEXARRAYATTRIBPROC EnableVertexArrayAttrib; + PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray; + PFNGLENABLEIPROC Enablei; + PFNGLENDPROC End; + PFNGLENDCONDITIONALRENDERPROC EndConditionalRender; + PFNGLENDLISTPROC EndList; + PFNGLENDQUERYPROC EndQuery; + PFNGLENDQUERYINDEXEDPROC EndQueryIndexed; + PFNGLENDTRANSFORMFEEDBACKPROC EndTransformFeedback; + PFNGLEVALCOORD1DPROC EvalCoord1d; + PFNGLEVALCOORD1DVPROC EvalCoord1dv; + PFNGLEVALCOORD1FPROC EvalCoord1f; + PFNGLEVALCOORD1FVPROC EvalCoord1fv; + PFNGLEVALCOORD2DPROC EvalCoord2d; + PFNGLEVALCOORD2DVPROC EvalCoord2dv; + PFNGLEVALCOORD2FPROC EvalCoord2f; + PFNGLEVALCOORD2FVPROC EvalCoord2fv; + PFNGLEVALMESH1PROC EvalMesh1; + PFNGLEVALMESH2PROC EvalMesh2; + PFNGLEVALPOINT1PROC EvalPoint1; + PFNGLEVALPOINT2PROC EvalPoint2; + PFNGLFEEDBACKBUFFERPROC FeedbackBuffer; + PFNGLFENCESYNCPROC FenceSync; + PFNGLFINISHPROC Finish; + PFNGLFLUSHPROC Flush; + PFNGLFLUSHMAPPEDBUFFERRANGEPROC FlushMappedBufferRange; + PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC FlushMappedNamedBufferRange; + PFNGLFOGCOORDPOINTERPROC FogCoordPointer; + PFNGLFOGCOORDDPROC FogCoordd; + PFNGLFOGCOORDDVPROC FogCoorddv; + PFNGLFOGCOORDFPROC FogCoordf; + PFNGLFOGCOORDFVPROC FogCoordfv; + PFNGLFOGFPROC Fogf; + PFNGLFOGFVPROC Fogfv; + PFNGLFOGIPROC Fogi; + PFNGLFOGIVPROC Fogiv; + PFNGLFRAMEBUFFERPARAMETERIPROC FramebufferParameteri; + PFNGLFRAMEBUFFERRENDERBUFFERPROC FramebufferRenderbuffer; + PFNGLFRAMEBUFFERTEXTUREPROC FramebufferTexture; + PFNGLFRAMEBUFFERTEXTURE1DPROC FramebufferTexture1D; + PFNGLFRAMEBUFFERTEXTURE2DPROC FramebufferTexture2D; + PFNGLFRAMEBUFFERTEXTURE3DPROC FramebufferTexture3D; + PFNGLFRAMEBUFFERTEXTURELAYERPROC FramebufferTextureLayer; + PFNGLFRONTFACEPROC FrontFace; + PFNGLFRUSTUMPROC Frustum; + PFNGLGENBUFFERSPROC GenBuffers; + PFNGLGENFRAMEBUFFERSPROC GenFramebuffers; + PFNGLGENLISTSPROC GenLists; + PFNGLGENPROGRAMPIPELINESPROC GenProgramPipelines; + PFNGLGENQUERIESPROC GenQueries; + PFNGLGENRENDERBUFFERSPROC GenRenderbuffers; + PFNGLGENSAMPLERSPROC GenSamplers; + PFNGLGENTEXTURESPROC GenTextures; + PFNGLGENTRANSFORMFEEDBACKSPROC GenTransformFeedbacks; + PFNGLGENVERTEXARRAYSPROC GenVertexArrays; + PFNGLGENERATEMIPMAPPROC GenerateMipmap; + PFNGLGENERATETEXTUREMIPMAPPROC GenerateTextureMipmap; + PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC GetActiveAtomicCounterBufferiv; + PFNGLGETACTIVEATTRIBPROC GetActiveAttrib; + PFNGLGETACTIVESUBROUTINENAMEPROC GetActiveSubroutineName; + PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC GetActiveSubroutineUniformName; + PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC GetActiveSubroutineUniformiv; + PFNGLGETACTIVEUNIFORMPROC GetActiveUniform; + PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC GetActiveUniformBlockName; + PFNGLGETACTIVEUNIFORMBLOCKIVPROC GetActiveUniformBlockiv; + PFNGLGETACTIVEUNIFORMNAMEPROC GetActiveUniformName; + PFNGLGETACTIVEUNIFORMSIVPROC GetActiveUniformsiv; + PFNGLGETATTACHEDSHADERSPROC GetAttachedShaders; + PFNGLGETATTRIBLOCATIONPROC GetAttribLocation; + PFNGLGETBOOLEANI_VPROC GetBooleani_v; + PFNGLGETBOOLEANVPROC GetBooleanv; + PFNGLGETBUFFERPARAMETERI64VPROC GetBufferParameteri64v; + PFNGLGETBUFFERPARAMETERIVPROC GetBufferParameteriv; + PFNGLGETBUFFERPOINTERVPROC GetBufferPointerv; + PFNGLGETBUFFERSUBDATAPROC GetBufferSubData; + PFNGLGETCLIPPLANEPROC GetClipPlane; + PFNGLGETCOMPRESSEDTEXIMAGEPROC GetCompressedTexImage; + PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC GetCompressedTextureImage; + PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC GetCompressedTextureSubImage; + PFNGLGETDEBUGMESSAGELOGPROC GetDebugMessageLog; + PFNGLGETDOUBLEI_VPROC GetDoublei_v; + PFNGLGETDOUBLEVPROC GetDoublev; + PFNGLGETERRORPROC GetError; + PFNGLGETFLOATI_VPROC GetFloati_v; + PFNGLGETFLOATVPROC GetFloatv; + PFNGLGETFRAGDATAINDEXPROC GetFragDataIndex; + PFNGLGETFRAGDATALOCATIONPROC GetFragDataLocation; + PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC GetFramebufferAttachmentParameteriv; + PFNGLGETFRAMEBUFFERPARAMETERIVPROC GetFramebufferParameteriv; + PFNGLGETGRAPHICSRESETSTATUSPROC GetGraphicsResetStatus; + PFNGLGETINTEGER64I_VPROC GetInteger64i_v; + PFNGLGETINTEGER64VPROC GetInteger64v; + PFNGLGETINTEGERI_VPROC GetIntegeri_v; + PFNGLGETINTEGERVPROC GetIntegerv; + PFNGLGETINTERNALFORMATI64VPROC GetInternalformati64v; + PFNGLGETINTERNALFORMATIVPROC GetInternalformativ; + PFNGLGETLIGHTFVPROC GetLightfv; + PFNGLGETLIGHTIVPROC GetLightiv; + PFNGLGETMAPDVPROC GetMapdv; + PFNGLGETMAPFVPROC GetMapfv; + PFNGLGETMAPIVPROC GetMapiv; + PFNGLGETMATERIALFVPROC GetMaterialfv; + PFNGLGETMATERIALIVPROC GetMaterialiv; + PFNGLGETMULTISAMPLEFVPROC GetMultisamplefv; + PFNGLGETNAMEDBUFFERPARAMETERI64VPROC GetNamedBufferParameteri64v; + PFNGLGETNAMEDBUFFERPARAMETERIVPROC GetNamedBufferParameteriv; + PFNGLGETNAMEDBUFFERPOINTERVPROC GetNamedBufferPointerv; + PFNGLGETNAMEDBUFFERSUBDATAPROC GetNamedBufferSubData; + PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC GetNamedFramebufferAttachmentParameteriv; + PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC GetNamedFramebufferParameteriv; + PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC GetNamedRenderbufferParameteriv; + PFNGLGETOBJECTLABELPROC GetObjectLabel; + PFNGLGETOBJECTPTRLABELPROC GetObjectPtrLabel; + PFNGLGETPIXELMAPFVPROC GetPixelMapfv; + PFNGLGETPIXELMAPUIVPROC GetPixelMapuiv; + PFNGLGETPIXELMAPUSVPROC GetPixelMapusv; + PFNGLGETPOINTERVPROC GetPointerv; + PFNGLGETPOLYGONSTIPPLEPROC GetPolygonStipple; + PFNGLGETPROGRAMBINARYPROC GetProgramBinary; + PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog; + PFNGLGETPROGRAMINTERFACEIVPROC GetProgramInterfaceiv; + PFNGLGETPROGRAMPIPELINEINFOLOGPROC GetProgramPipelineInfoLog; + PFNGLGETPROGRAMPIPELINEIVPROC GetProgramPipelineiv; + PFNGLGETPROGRAMRESOURCEINDEXPROC GetProgramResourceIndex; + PFNGLGETPROGRAMRESOURCELOCATIONPROC GetProgramResourceLocation; + PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC GetProgramResourceLocationIndex; + PFNGLGETPROGRAMRESOURCENAMEPROC GetProgramResourceName; + PFNGLGETPROGRAMRESOURCEIVPROC GetProgramResourceiv; + PFNGLGETPROGRAMSTAGEIVPROC GetProgramStageiv; + PFNGLGETPROGRAMIVPROC GetProgramiv; + PFNGLGETQUERYBUFFEROBJECTI64VPROC GetQueryBufferObjecti64v; + PFNGLGETQUERYBUFFEROBJECTIVPROC GetQueryBufferObjectiv; + PFNGLGETQUERYBUFFEROBJECTUI64VPROC GetQueryBufferObjectui64v; + PFNGLGETQUERYBUFFEROBJECTUIVPROC GetQueryBufferObjectuiv; + PFNGLGETQUERYINDEXEDIVPROC GetQueryIndexediv; + PFNGLGETQUERYOBJECTI64VPROC GetQueryObjecti64v; + PFNGLGETQUERYOBJECTIVPROC GetQueryObjectiv; + PFNGLGETQUERYOBJECTUI64VPROC GetQueryObjectui64v; + PFNGLGETQUERYOBJECTUIVPROC GetQueryObjectuiv; + PFNGLGETQUERYIVPROC GetQueryiv; + PFNGLGETRENDERBUFFERPARAMETERIVPROC GetRenderbufferParameteriv; + PFNGLGETSAMPLERPARAMETERIIVPROC GetSamplerParameterIiv; + PFNGLGETSAMPLERPARAMETERIUIVPROC GetSamplerParameterIuiv; + PFNGLGETSAMPLERPARAMETERFVPROC GetSamplerParameterfv; + PFNGLGETSAMPLERPARAMETERIVPROC GetSamplerParameteriv; + PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog; + PFNGLGETSHADERPRECISIONFORMATPROC GetShaderPrecisionFormat; + PFNGLGETSHADERSOURCEPROC GetShaderSource; + PFNGLGETSHADERIVPROC GetShaderiv; + PFNGLGETSTRINGPROC GetString; + PFNGLGETSTRINGIPROC GetStringi; + PFNGLGETSUBROUTINEINDEXPROC GetSubroutineIndex; + PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC GetSubroutineUniformLocation; + PFNGLGETSYNCIVPROC GetSynciv; + PFNGLGETTEXENVFVPROC GetTexEnvfv; + PFNGLGETTEXENVIVPROC GetTexEnviv; + PFNGLGETTEXGENDVPROC GetTexGendv; + PFNGLGETTEXGENFVPROC GetTexGenfv; + PFNGLGETTEXGENIVPROC GetTexGeniv; + PFNGLGETTEXIMAGEPROC GetTexImage; + PFNGLGETTEXLEVELPARAMETERFVPROC GetTexLevelParameterfv; + PFNGLGETTEXLEVELPARAMETERIVPROC GetTexLevelParameteriv; + PFNGLGETTEXPARAMETERIIVPROC GetTexParameterIiv; + PFNGLGETTEXPARAMETERIUIVPROC GetTexParameterIuiv; + PFNGLGETTEXPARAMETERFVPROC GetTexParameterfv; + PFNGLGETTEXPARAMETERIVPROC GetTexParameteriv; + PFNGLGETTEXTUREIMAGEPROC GetTextureImage; + PFNGLGETTEXTURELEVELPARAMETERFVPROC GetTextureLevelParameterfv; + PFNGLGETTEXTURELEVELPARAMETERIVPROC GetTextureLevelParameteriv; + PFNGLGETTEXTUREPARAMETERIIVPROC GetTextureParameterIiv; + PFNGLGETTEXTUREPARAMETERIUIVPROC GetTextureParameterIuiv; + PFNGLGETTEXTUREPARAMETERFVPROC GetTextureParameterfv; + PFNGLGETTEXTUREPARAMETERIVPROC GetTextureParameteriv; + PFNGLGETTEXTURESUBIMAGEPROC GetTextureSubImage; + PFNGLGETTRANSFORMFEEDBACKVARYINGPROC GetTransformFeedbackVarying; + PFNGLGETTRANSFORMFEEDBACKI64_VPROC GetTransformFeedbacki64_v; + PFNGLGETTRANSFORMFEEDBACKI_VPROC GetTransformFeedbacki_v; + PFNGLGETTRANSFORMFEEDBACKIVPROC GetTransformFeedbackiv; + PFNGLGETUNIFORMBLOCKINDEXPROC GetUniformBlockIndex; + PFNGLGETUNIFORMINDICESPROC GetUniformIndices; + PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation; + PFNGLGETUNIFORMSUBROUTINEUIVPROC GetUniformSubroutineuiv; + PFNGLGETUNIFORMDVPROC GetUniformdv; + PFNGLGETUNIFORMFVPROC GetUniformfv; + PFNGLGETUNIFORMIVPROC GetUniformiv; + PFNGLGETUNIFORMUIVPROC GetUniformuiv; + PFNGLGETVERTEXARRAYINDEXED64IVPROC GetVertexArrayIndexed64iv; + PFNGLGETVERTEXARRAYINDEXEDIVPROC GetVertexArrayIndexediv; + PFNGLGETVERTEXARRAYIVPROC GetVertexArrayiv; + PFNGLGETVERTEXATTRIBIIVPROC GetVertexAttribIiv; + PFNGLGETVERTEXATTRIBIUIVPROC GetVertexAttribIuiv; + PFNGLGETVERTEXATTRIBLDVPROC GetVertexAttribLdv; + PFNGLGETVERTEXATTRIBPOINTERVPROC GetVertexAttribPointerv; + PFNGLGETVERTEXATTRIBDVPROC GetVertexAttribdv; + PFNGLGETVERTEXATTRIBFVPROC GetVertexAttribfv; + PFNGLGETVERTEXATTRIBIVPROC GetVertexAttribiv; + PFNGLGETNCOLORTABLEPROC GetnColorTable; + PFNGLGETNCOMPRESSEDTEXIMAGEPROC GetnCompressedTexImage; + PFNGLGETNCONVOLUTIONFILTERPROC GetnConvolutionFilter; + PFNGLGETNHISTOGRAMPROC GetnHistogram; + PFNGLGETNMAPDVPROC GetnMapdv; + PFNGLGETNMAPFVPROC GetnMapfv; + PFNGLGETNMAPIVPROC GetnMapiv; + PFNGLGETNMINMAXPROC GetnMinmax; + PFNGLGETNPIXELMAPFVPROC GetnPixelMapfv; + PFNGLGETNPIXELMAPUIVPROC GetnPixelMapuiv; + PFNGLGETNPIXELMAPUSVPROC GetnPixelMapusv; + PFNGLGETNPOLYGONSTIPPLEPROC GetnPolygonStipple; + PFNGLGETNSEPARABLEFILTERPROC GetnSeparableFilter; + PFNGLGETNTEXIMAGEPROC GetnTexImage; + PFNGLGETNUNIFORMDVPROC GetnUniformdv; + PFNGLGETNUNIFORMFVPROC GetnUniformfv; + PFNGLGETNUNIFORMIVPROC GetnUniformiv; + PFNGLGETNUNIFORMUIVPROC GetnUniformuiv; + PFNGLHINTPROC Hint; + PFNGLINDEXMASKPROC IndexMask; + PFNGLINDEXPOINTERPROC IndexPointer; + PFNGLINDEXDPROC Indexd; + PFNGLINDEXDVPROC Indexdv; + PFNGLINDEXFPROC Indexf; + PFNGLINDEXFVPROC Indexfv; + PFNGLINDEXIPROC Indexi; + PFNGLINDEXIVPROC Indexiv; + PFNGLINDEXSPROC Indexs; + PFNGLINDEXSVPROC Indexsv; + PFNGLINDEXUBPROC Indexub; + PFNGLINDEXUBVPROC Indexubv; + PFNGLINITNAMESPROC InitNames; + PFNGLINTERLEAVEDARRAYSPROC InterleavedArrays; + PFNGLINVALIDATEBUFFERDATAPROC InvalidateBufferData; + PFNGLINVALIDATEBUFFERSUBDATAPROC InvalidateBufferSubData; + PFNGLINVALIDATEFRAMEBUFFERPROC InvalidateFramebuffer; + PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC InvalidateNamedFramebufferData; + PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC InvalidateNamedFramebufferSubData; + PFNGLINVALIDATESUBFRAMEBUFFERPROC InvalidateSubFramebuffer; + PFNGLINVALIDATETEXIMAGEPROC InvalidateTexImage; + PFNGLINVALIDATETEXSUBIMAGEPROC InvalidateTexSubImage; + PFNGLISBUFFERPROC IsBuffer; + PFNGLISENABLEDPROC IsEnabled; + PFNGLISENABLEDIPROC IsEnabledi; + PFNGLISFRAMEBUFFERPROC IsFramebuffer; + PFNGLISLISTPROC IsList; + PFNGLISPROGRAMPROC IsProgram; + PFNGLISPROGRAMPIPELINEPROC IsProgramPipeline; + PFNGLISQUERYPROC IsQuery; + PFNGLISRENDERBUFFERPROC IsRenderbuffer; + PFNGLISSAMPLERPROC IsSampler; + PFNGLISSHADERPROC IsShader; + PFNGLISSYNCPROC IsSync; + PFNGLISTEXTUREPROC IsTexture; + PFNGLISTRANSFORMFEEDBACKPROC IsTransformFeedback; + PFNGLISVERTEXARRAYPROC IsVertexArray; + PFNGLLIGHTMODELFPROC LightModelf; + PFNGLLIGHTMODELFVPROC LightModelfv; + PFNGLLIGHTMODELIPROC LightModeli; + PFNGLLIGHTMODELIVPROC LightModeliv; + PFNGLLIGHTFPROC Lightf; + PFNGLLIGHTFVPROC Lightfv; + PFNGLLIGHTIPROC Lighti; + PFNGLLIGHTIVPROC Lightiv; + PFNGLLINESTIPPLEPROC LineStipple; + PFNGLLINEWIDTHPROC LineWidth; + PFNGLLINKPROGRAMPROC LinkProgram; + PFNGLLISTBASEPROC ListBase; + PFNGLLOADIDENTITYPROC LoadIdentity; + PFNGLLOADMATRIXDPROC LoadMatrixd; + PFNGLLOADMATRIXFPROC LoadMatrixf; + PFNGLLOADNAMEPROC LoadName; + PFNGLLOADTRANSPOSEMATRIXDPROC LoadTransposeMatrixd; + PFNGLLOADTRANSPOSEMATRIXFPROC LoadTransposeMatrixf; + PFNGLLOGICOPPROC LogicOp; + PFNGLMAP1DPROC Map1d; + PFNGLMAP1FPROC Map1f; + PFNGLMAP2DPROC Map2d; + PFNGLMAP2FPROC Map2f; + PFNGLMAPBUFFERPROC MapBuffer; + PFNGLMAPBUFFERRANGEPROC MapBufferRange; + PFNGLMAPGRID1DPROC MapGrid1d; + PFNGLMAPGRID1FPROC MapGrid1f; + PFNGLMAPGRID2DPROC MapGrid2d; + PFNGLMAPGRID2FPROC MapGrid2f; + PFNGLMAPNAMEDBUFFERPROC MapNamedBuffer; + PFNGLMAPNAMEDBUFFERRANGEPROC MapNamedBufferRange; + PFNGLMATERIALFPROC Materialf; + PFNGLMATERIALFVPROC Materialfv; + PFNGLMATERIALIPROC Materiali; + PFNGLMATERIALIVPROC Materialiv; + PFNGLMATRIXMODEPROC MatrixMode; + PFNGLMEMORYBARRIERPROC MemoryBarrier; + PFNGLMEMORYBARRIERBYREGIONPROC MemoryBarrierByRegion; + PFNGLMINSAMPLESHADINGPROC MinSampleShading; + PFNGLMULTMATRIXDPROC MultMatrixd; + PFNGLMULTMATRIXFPROC MultMatrixf; + PFNGLMULTTRANSPOSEMATRIXDPROC MultTransposeMatrixd; + PFNGLMULTTRANSPOSEMATRIXFPROC MultTransposeMatrixf; + PFNGLMULTIDRAWARRAYSPROC MultiDrawArrays; + PFNGLMULTIDRAWARRAYSINDIRECTPROC MultiDrawArraysIndirect; + PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC MultiDrawArraysIndirectCount; + PFNGLMULTIDRAWELEMENTSPROC MultiDrawElements; + PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC MultiDrawElementsBaseVertex; + PFNGLMULTIDRAWELEMENTSINDIRECTPROC MultiDrawElementsIndirect; + PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC MultiDrawElementsIndirectCount; + PFNGLMULTITEXCOORD1DPROC MultiTexCoord1d; + PFNGLMULTITEXCOORD1DVPROC MultiTexCoord1dv; + PFNGLMULTITEXCOORD1FPROC MultiTexCoord1f; + PFNGLMULTITEXCOORD1FVPROC MultiTexCoord1fv; + PFNGLMULTITEXCOORD1IPROC MultiTexCoord1i; + PFNGLMULTITEXCOORD1IVPROC MultiTexCoord1iv; + PFNGLMULTITEXCOORD1SPROC MultiTexCoord1s; + PFNGLMULTITEXCOORD1SVPROC MultiTexCoord1sv; + PFNGLMULTITEXCOORD2DPROC MultiTexCoord2d; + PFNGLMULTITEXCOORD2DVPROC MultiTexCoord2dv; + PFNGLMULTITEXCOORD2FPROC MultiTexCoord2f; + PFNGLMULTITEXCOORD2FVPROC MultiTexCoord2fv; + PFNGLMULTITEXCOORD2IPROC MultiTexCoord2i; + PFNGLMULTITEXCOORD2IVPROC MultiTexCoord2iv; + PFNGLMULTITEXCOORD2SPROC MultiTexCoord2s; + PFNGLMULTITEXCOORD2SVPROC MultiTexCoord2sv; + PFNGLMULTITEXCOORD3DPROC MultiTexCoord3d; + PFNGLMULTITEXCOORD3DVPROC MultiTexCoord3dv; + PFNGLMULTITEXCOORD3FPROC MultiTexCoord3f; + PFNGLMULTITEXCOORD3FVPROC MultiTexCoord3fv; + PFNGLMULTITEXCOORD3IPROC MultiTexCoord3i; + PFNGLMULTITEXCOORD3IVPROC MultiTexCoord3iv; + PFNGLMULTITEXCOORD3SPROC MultiTexCoord3s; + PFNGLMULTITEXCOORD3SVPROC MultiTexCoord3sv; + PFNGLMULTITEXCOORD4DPROC MultiTexCoord4d; + PFNGLMULTITEXCOORD4DVPROC MultiTexCoord4dv; + PFNGLMULTITEXCOORD4FPROC MultiTexCoord4f; + PFNGLMULTITEXCOORD4FVPROC MultiTexCoord4fv; + PFNGLMULTITEXCOORD4IPROC MultiTexCoord4i; + PFNGLMULTITEXCOORD4IVPROC MultiTexCoord4iv; + PFNGLMULTITEXCOORD4SPROC MultiTexCoord4s; + PFNGLMULTITEXCOORD4SVPROC MultiTexCoord4sv; + PFNGLMULTITEXCOORDP1UIPROC MultiTexCoordP1ui; + PFNGLMULTITEXCOORDP1UIVPROC MultiTexCoordP1uiv; + PFNGLMULTITEXCOORDP2UIPROC MultiTexCoordP2ui; + PFNGLMULTITEXCOORDP2UIVPROC MultiTexCoordP2uiv; + PFNGLMULTITEXCOORDP3UIPROC MultiTexCoordP3ui; + PFNGLMULTITEXCOORDP3UIVPROC MultiTexCoordP3uiv; + PFNGLMULTITEXCOORDP4UIPROC MultiTexCoordP4ui; + PFNGLMULTITEXCOORDP4UIVPROC MultiTexCoordP4uiv; + PFNGLNAMEDBUFFERDATAPROC NamedBufferData; + PFNGLNAMEDBUFFERSTORAGEPROC NamedBufferStorage; + PFNGLNAMEDBUFFERSUBDATAPROC NamedBufferSubData; + PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC NamedFramebufferDrawBuffer; + PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC NamedFramebufferDrawBuffers; + PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC NamedFramebufferParameteri; + PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC NamedFramebufferReadBuffer; + PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC NamedFramebufferRenderbuffer; + PFNGLNAMEDFRAMEBUFFERTEXTUREPROC NamedFramebufferTexture; + PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC NamedFramebufferTextureLayer; + PFNGLNAMEDRENDERBUFFERSTORAGEPROC NamedRenderbufferStorage; + PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC NamedRenderbufferStorageMultisample; + PFNGLNEWLISTPROC NewList; + PFNGLNORMAL3BPROC Normal3b; + PFNGLNORMAL3BVPROC Normal3bv; + PFNGLNORMAL3DPROC Normal3d; + PFNGLNORMAL3DVPROC Normal3dv; + PFNGLNORMAL3FPROC Normal3f; + PFNGLNORMAL3FVPROC Normal3fv; + PFNGLNORMAL3IPROC Normal3i; + PFNGLNORMAL3IVPROC Normal3iv; + PFNGLNORMAL3SPROC Normal3s; + PFNGLNORMAL3SVPROC Normal3sv; + PFNGLNORMALP3UIPROC NormalP3ui; + PFNGLNORMALP3UIVPROC NormalP3uiv; + PFNGLNORMALPOINTERPROC NormalPointer; + PFNGLOBJECTLABELPROC ObjectLabel; + PFNGLOBJECTPTRLABELPROC ObjectPtrLabel; + PFNGLORTHOPROC Ortho; + PFNGLPASSTHROUGHPROC PassThrough; + PFNGLPATCHPARAMETERFVPROC PatchParameterfv; + PFNGLPATCHPARAMETERIPROC PatchParameteri; + PFNGLPAUSETRANSFORMFEEDBACKPROC PauseTransformFeedback; + PFNGLPIXELMAPFVPROC PixelMapfv; + PFNGLPIXELMAPUIVPROC PixelMapuiv; + PFNGLPIXELMAPUSVPROC PixelMapusv; + PFNGLPIXELSTOREFPROC PixelStoref; + PFNGLPIXELSTOREIPROC PixelStorei; + PFNGLPIXELTRANSFERFPROC PixelTransferf; + PFNGLPIXELTRANSFERIPROC PixelTransferi; + PFNGLPIXELZOOMPROC PixelZoom; + PFNGLPOINTPARAMETERFPROC PointParameterf; + PFNGLPOINTPARAMETERFVPROC PointParameterfv; + PFNGLPOINTPARAMETERIPROC PointParameteri; + PFNGLPOINTPARAMETERIVPROC PointParameteriv; + PFNGLPOINTSIZEPROC PointSize; + PFNGLPOLYGONMODEPROC PolygonMode; + PFNGLPOLYGONOFFSETPROC PolygonOffset; + PFNGLPOLYGONOFFSETCLAMPPROC PolygonOffsetClamp; + PFNGLPOLYGONSTIPPLEPROC PolygonStipple; + PFNGLPOPATTRIBPROC PopAttrib; + PFNGLPOPCLIENTATTRIBPROC PopClientAttrib; + PFNGLPOPDEBUGGROUPPROC PopDebugGroup; + PFNGLPOPMATRIXPROC PopMatrix; + PFNGLPOPNAMEPROC PopName; + PFNGLPRIMITIVERESTARTINDEXPROC PrimitiveRestartIndex; + PFNGLPRIORITIZETEXTURESPROC PrioritizeTextures; + PFNGLPROGRAMBINARYPROC ProgramBinary; + PFNGLPROGRAMPARAMETERIPROC ProgramParameteri; + PFNGLPROGRAMUNIFORM1DPROC ProgramUniform1d; + PFNGLPROGRAMUNIFORM1DVPROC ProgramUniform1dv; + PFNGLPROGRAMUNIFORM1FPROC ProgramUniform1f; + PFNGLPROGRAMUNIFORM1FVPROC ProgramUniform1fv; + PFNGLPROGRAMUNIFORM1IPROC ProgramUniform1i; + PFNGLPROGRAMUNIFORM1IVPROC ProgramUniform1iv; + PFNGLPROGRAMUNIFORM1UIPROC ProgramUniform1ui; + PFNGLPROGRAMUNIFORM1UIVPROC ProgramUniform1uiv; + PFNGLPROGRAMUNIFORM2DPROC ProgramUniform2d; + PFNGLPROGRAMUNIFORM2DVPROC ProgramUniform2dv; + PFNGLPROGRAMUNIFORM2FPROC ProgramUniform2f; + PFNGLPROGRAMUNIFORM2FVPROC ProgramUniform2fv; + PFNGLPROGRAMUNIFORM2IPROC ProgramUniform2i; + PFNGLPROGRAMUNIFORM2IVPROC ProgramUniform2iv; + PFNGLPROGRAMUNIFORM2UIPROC ProgramUniform2ui; + PFNGLPROGRAMUNIFORM2UIVPROC ProgramUniform2uiv; + PFNGLPROGRAMUNIFORM3DPROC ProgramUniform3d; + PFNGLPROGRAMUNIFORM3DVPROC ProgramUniform3dv; + PFNGLPROGRAMUNIFORM3FPROC ProgramUniform3f; + PFNGLPROGRAMUNIFORM3FVPROC ProgramUniform3fv; + PFNGLPROGRAMUNIFORM3IPROC ProgramUniform3i; + PFNGLPROGRAMUNIFORM3IVPROC ProgramUniform3iv; + PFNGLPROGRAMUNIFORM3UIPROC ProgramUniform3ui; + PFNGLPROGRAMUNIFORM3UIVPROC ProgramUniform3uiv; + PFNGLPROGRAMUNIFORM4DPROC ProgramUniform4d; + PFNGLPROGRAMUNIFORM4DVPROC ProgramUniform4dv; + PFNGLPROGRAMUNIFORM4FPROC ProgramUniform4f; + PFNGLPROGRAMUNIFORM4FVPROC ProgramUniform4fv; + PFNGLPROGRAMUNIFORM4IPROC ProgramUniform4i; + PFNGLPROGRAMUNIFORM4IVPROC ProgramUniform4iv; + PFNGLPROGRAMUNIFORM4UIPROC ProgramUniform4ui; + PFNGLPROGRAMUNIFORM4UIVPROC ProgramUniform4uiv; + PFNGLPROGRAMUNIFORMMATRIX2DVPROC ProgramUniformMatrix2dv; + PFNGLPROGRAMUNIFORMMATRIX2FVPROC ProgramUniformMatrix2fv; + PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC ProgramUniformMatrix2x3dv; + PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC ProgramUniformMatrix2x3fv; + PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC ProgramUniformMatrix2x4dv; + PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC ProgramUniformMatrix2x4fv; + PFNGLPROGRAMUNIFORMMATRIX3DVPROC ProgramUniformMatrix3dv; + PFNGLPROGRAMUNIFORMMATRIX3FVPROC ProgramUniformMatrix3fv; + PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC ProgramUniformMatrix3x2dv; + PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC ProgramUniformMatrix3x2fv; + PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC ProgramUniformMatrix3x4dv; + PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC ProgramUniformMatrix3x4fv; + PFNGLPROGRAMUNIFORMMATRIX4DVPROC ProgramUniformMatrix4dv; + PFNGLPROGRAMUNIFORMMATRIX4FVPROC ProgramUniformMatrix4fv; + PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC ProgramUniformMatrix4x2dv; + PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC ProgramUniformMatrix4x2fv; + PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC ProgramUniformMatrix4x3dv; + PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC ProgramUniformMatrix4x3fv; + PFNGLPROVOKINGVERTEXPROC ProvokingVertex; + PFNGLPUSHATTRIBPROC PushAttrib; + PFNGLPUSHCLIENTATTRIBPROC PushClientAttrib; + PFNGLPUSHDEBUGGROUPPROC PushDebugGroup; + PFNGLPUSHMATRIXPROC PushMatrix; + PFNGLPUSHNAMEPROC PushName; + PFNGLQUERYCOUNTERPROC QueryCounter; + PFNGLRASTERPOS2DPROC RasterPos2d; + PFNGLRASTERPOS2DVPROC RasterPos2dv; + PFNGLRASTERPOS2FPROC RasterPos2f; + PFNGLRASTERPOS2FVPROC RasterPos2fv; + PFNGLRASTERPOS2IPROC RasterPos2i; + PFNGLRASTERPOS2IVPROC RasterPos2iv; + PFNGLRASTERPOS2SPROC RasterPos2s; + PFNGLRASTERPOS2SVPROC RasterPos2sv; + PFNGLRASTERPOS3DPROC RasterPos3d; + PFNGLRASTERPOS3DVPROC RasterPos3dv; + PFNGLRASTERPOS3FPROC RasterPos3f; + PFNGLRASTERPOS3FVPROC RasterPos3fv; + PFNGLRASTERPOS3IPROC RasterPos3i; + PFNGLRASTERPOS3IVPROC RasterPos3iv; + PFNGLRASTERPOS3SPROC RasterPos3s; + PFNGLRASTERPOS3SVPROC RasterPos3sv; + PFNGLRASTERPOS4DPROC RasterPos4d; + PFNGLRASTERPOS4DVPROC RasterPos4dv; + PFNGLRASTERPOS4FPROC RasterPos4f; + PFNGLRASTERPOS4FVPROC RasterPos4fv; + PFNGLRASTERPOS4IPROC RasterPos4i; + PFNGLRASTERPOS4IVPROC RasterPos4iv; + PFNGLRASTERPOS4SPROC RasterPos4s; + PFNGLRASTERPOS4SVPROC RasterPos4sv; + PFNGLREADBUFFERPROC ReadBuffer; + PFNGLREADPIXELSPROC ReadPixels; + PFNGLREADNPIXELSPROC ReadnPixels; + PFNGLRECTDPROC Rectd; + PFNGLRECTDVPROC Rectdv; + PFNGLRECTFPROC Rectf; + PFNGLRECTFVPROC Rectfv; + PFNGLRECTIPROC Recti; + PFNGLRECTIVPROC Rectiv; + PFNGLRECTSPROC Rects; + PFNGLRECTSVPROC Rectsv; + PFNGLRELEASESHADERCOMPILERPROC ReleaseShaderCompiler; + PFNGLRENDERMODEPROC RenderMode; + PFNGLRENDERBUFFERSTORAGEPROC RenderbufferStorage; + PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC RenderbufferStorageMultisample; + PFNGLRESUMETRANSFORMFEEDBACKPROC ResumeTransformFeedback; + PFNGLROTATEDPROC Rotated; + PFNGLROTATEFPROC Rotatef; + PFNGLSAMPLECOVERAGEPROC SampleCoverage; + PFNGLSAMPLEMASKIPROC SampleMaski; + PFNGLSAMPLERPARAMETERIIVPROC SamplerParameterIiv; + PFNGLSAMPLERPARAMETERIUIVPROC SamplerParameterIuiv; + PFNGLSAMPLERPARAMETERFPROC SamplerParameterf; + PFNGLSAMPLERPARAMETERFVPROC SamplerParameterfv; + PFNGLSAMPLERPARAMETERIPROC SamplerParameteri; + PFNGLSAMPLERPARAMETERIVPROC SamplerParameteriv; + PFNGLSCALEDPROC Scaled; + PFNGLSCALEFPROC Scalef; + PFNGLSCISSORPROC Scissor; + PFNGLSCISSORARRAYVPROC ScissorArrayv; + PFNGLSCISSORINDEXEDPROC ScissorIndexed; + PFNGLSCISSORINDEXEDVPROC ScissorIndexedv; + PFNGLSECONDARYCOLOR3BPROC SecondaryColor3b; + PFNGLSECONDARYCOLOR3BVPROC SecondaryColor3bv; + PFNGLSECONDARYCOLOR3DPROC SecondaryColor3d; + PFNGLSECONDARYCOLOR3DVPROC SecondaryColor3dv; + PFNGLSECONDARYCOLOR3FPROC SecondaryColor3f; + PFNGLSECONDARYCOLOR3FVPROC SecondaryColor3fv; + PFNGLSECONDARYCOLOR3IPROC SecondaryColor3i; + PFNGLSECONDARYCOLOR3IVPROC SecondaryColor3iv; + PFNGLSECONDARYCOLOR3SPROC SecondaryColor3s; + PFNGLSECONDARYCOLOR3SVPROC SecondaryColor3sv; + PFNGLSECONDARYCOLOR3UBPROC SecondaryColor3ub; + PFNGLSECONDARYCOLOR3UBVPROC SecondaryColor3ubv; + PFNGLSECONDARYCOLOR3UIPROC SecondaryColor3ui; + PFNGLSECONDARYCOLOR3UIVPROC SecondaryColor3uiv; + PFNGLSECONDARYCOLOR3USPROC SecondaryColor3us; + PFNGLSECONDARYCOLOR3USVPROC SecondaryColor3usv; + PFNGLSECONDARYCOLORP3UIPROC SecondaryColorP3ui; + PFNGLSECONDARYCOLORP3UIVPROC SecondaryColorP3uiv; + PFNGLSECONDARYCOLORPOINTERPROC SecondaryColorPointer; + PFNGLSELECTBUFFERPROC SelectBuffer; + PFNGLSHADEMODELPROC ShadeModel; + PFNGLSHADERBINARYPROC ShaderBinary; + PFNGLSHADERSOURCEPROC ShaderSource; + PFNGLSHADERSTORAGEBLOCKBINDINGPROC ShaderStorageBlockBinding; + PFNGLSPECIALIZESHADERPROC SpecializeShader; + PFNGLSTENCILFUNCPROC StencilFunc; + PFNGLSTENCILFUNCSEPARATEPROC StencilFuncSeparate; + PFNGLSTENCILMASKPROC StencilMask; + PFNGLSTENCILMASKSEPARATEPROC StencilMaskSeparate; + PFNGLSTENCILOPPROC StencilOp; + PFNGLSTENCILOPSEPARATEPROC StencilOpSeparate; + PFNGLTEXBUFFERPROC TexBuffer; + PFNGLTEXBUFFERRANGEPROC TexBufferRange; + PFNGLTEXCOORD1DPROC TexCoord1d; + PFNGLTEXCOORD1DVPROC TexCoord1dv; + PFNGLTEXCOORD1FPROC TexCoord1f; + PFNGLTEXCOORD1FVPROC TexCoord1fv; + PFNGLTEXCOORD1IPROC TexCoord1i; + PFNGLTEXCOORD1IVPROC TexCoord1iv; + PFNGLTEXCOORD1SPROC TexCoord1s; + PFNGLTEXCOORD1SVPROC TexCoord1sv; + PFNGLTEXCOORD2DPROC TexCoord2d; + PFNGLTEXCOORD2DVPROC TexCoord2dv; + PFNGLTEXCOORD2FPROC TexCoord2f; + PFNGLTEXCOORD2FVPROC TexCoord2fv; + PFNGLTEXCOORD2IPROC TexCoord2i; + PFNGLTEXCOORD2IVPROC TexCoord2iv; + PFNGLTEXCOORD2SPROC TexCoord2s; + PFNGLTEXCOORD2SVPROC TexCoord2sv; + PFNGLTEXCOORD3DPROC TexCoord3d; + PFNGLTEXCOORD3DVPROC TexCoord3dv; + PFNGLTEXCOORD3FPROC TexCoord3f; + PFNGLTEXCOORD3FVPROC TexCoord3fv; + PFNGLTEXCOORD3IPROC TexCoord3i; + PFNGLTEXCOORD3IVPROC TexCoord3iv; + PFNGLTEXCOORD3SPROC TexCoord3s; + PFNGLTEXCOORD3SVPROC TexCoord3sv; + PFNGLTEXCOORD4DPROC TexCoord4d; + PFNGLTEXCOORD4DVPROC TexCoord4dv; + PFNGLTEXCOORD4FPROC TexCoord4f; + PFNGLTEXCOORD4FVPROC TexCoord4fv; + PFNGLTEXCOORD4IPROC TexCoord4i; + PFNGLTEXCOORD4IVPROC TexCoord4iv; + PFNGLTEXCOORD4SPROC TexCoord4s; + PFNGLTEXCOORD4SVPROC TexCoord4sv; + PFNGLTEXCOORDP1UIPROC TexCoordP1ui; + PFNGLTEXCOORDP1UIVPROC TexCoordP1uiv; + PFNGLTEXCOORDP2UIPROC TexCoordP2ui; + PFNGLTEXCOORDP2UIVPROC TexCoordP2uiv; + PFNGLTEXCOORDP3UIPROC TexCoordP3ui; + PFNGLTEXCOORDP3UIVPROC TexCoordP3uiv; + PFNGLTEXCOORDP4UIPROC TexCoordP4ui; + PFNGLTEXCOORDP4UIVPROC TexCoordP4uiv; + PFNGLTEXCOORDPOINTERPROC TexCoordPointer; + PFNGLTEXENVFPROC TexEnvf; + PFNGLTEXENVFVPROC TexEnvfv; + PFNGLTEXENVIPROC TexEnvi; + PFNGLTEXENVIVPROC TexEnviv; + PFNGLTEXGENDPROC TexGend; + PFNGLTEXGENDVPROC TexGendv; + PFNGLTEXGENFPROC TexGenf; + PFNGLTEXGENFVPROC TexGenfv; + PFNGLTEXGENIPROC TexGeni; + PFNGLTEXGENIVPROC TexGeniv; + PFNGLTEXIMAGE1DPROC TexImage1D; + PFNGLTEXIMAGE2DPROC TexImage2D; + PFNGLTEXIMAGE2DMULTISAMPLEPROC TexImage2DMultisample; + PFNGLTEXIMAGE3DPROC TexImage3D; + PFNGLTEXIMAGE3DMULTISAMPLEPROC TexImage3DMultisample; + PFNGLTEXPARAMETERIIVPROC TexParameterIiv; + PFNGLTEXPARAMETERIUIVPROC TexParameterIuiv; + PFNGLTEXPARAMETERFPROC TexParameterf; + PFNGLTEXPARAMETERFVPROC TexParameterfv; + PFNGLTEXPARAMETERIPROC TexParameteri; + PFNGLTEXPARAMETERIVPROC TexParameteriv; + PFNGLTEXSTORAGE1DPROC TexStorage1D; + PFNGLTEXSTORAGE2DPROC TexStorage2D; + PFNGLTEXSTORAGE2DMULTISAMPLEPROC TexStorage2DMultisample; + PFNGLTEXSTORAGE3DPROC TexStorage3D; + PFNGLTEXSTORAGE3DMULTISAMPLEPROC TexStorage3DMultisample; + PFNGLTEXSUBIMAGE1DPROC TexSubImage1D; + PFNGLTEXSUBIMAGE2DPROC TexSubImage2D; + PFNGLTEXSUBIMAGE3DPROC TexSubImage3D; + PFNGLTEXTUREBARRIERPROC TextureBarrier; + PFNGLTEXTUREBUFFERPROC TextureBuffer; + PFNGLTEXTUREBUFFERRANGEPROC TextureBufferRange; + PFNGLTEXTUREPARAMETERIIVPROC TextureParameterIiv; + PFNGLTEXTUREPARAMETERIUIVPROC TextureParameterIuiv; + PFNGLTEXTUREPARAMETERFPROC TextureParameterf; + PFNGLTEXTUREPARAMETERFVPROC TextureParameterfv; + PFNGLTEXTUREPARAMETERIPROC TextureParameteri; + PFNGLTEXTUREPARAMETERIVPROC TextureParameteriv; + PFNGLTEXTURESTORAGE1DPROC TextureStorage1D; + PFNGLTEXTURESTORAGE2DPROC TextureStorage2D; + PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC TextureStorage2DMultisample; + PFNGLTEXTURESTORAGE3DPROC TextureStorage3D; + PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC TextureStorage3DMultisample; + PFNGLTEXTURESUBIMAGE1DPROC TextureSubImage1D; + PFNGLTEXTURESUBIMAGE2DPROC TextureSubImage2D; + PFNGLTEXTURESUBIMAGE3DPROC TextureSubImage3D; + PFNGLTEXTUREVIEWPROC TextureView; + PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC TransformFeedbackBufferBase; + PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC TransformFeedbackBufferRange; + PFNGLTRANSFORMFEEDBACKVARYINGSPROC TransformFeedbackVaryings; + PFNGLTRANSLATEDPROC Translated; + PFNGLTRANSLATEFPROC Translatef; + PFNGLUNIFORM1DPROC Uniform1d; + PFNGLUNIFORM1DVPROC Uniform1dv; + PFNGLUNIFORM1FPROC Uniform1f; + PFNGLUNIFORM1FVPROC Uniform1fv; + PFNGLUNIFORM1IPROC Uniform1i; + PFNGLUNIFORM1IVPROC Uniform1iv; + PFNGLUNIFORM1UIPROC Uniform1ui; + PFNGLUNIFORM1UIVPROC Uniform1uiv; + PFNGLUNIFORM2DPROC Uniform2d; + PFNGLUNIFORM2DVPROC Uniform2dv; + PFNGLUNIFORM2FPROC Uniform2f; + PFNGLUNIFORM2FVPROC Uniform2fv; + PFNGLUNIFORM2IPROC Uniform2i; + PFNGLUNIFORM2IVPROC Uniform2iv; + PFNGLUNIFORM2UIPROC Uniform2ui; + PFNGLUNIFORM2UIVPROC Uniform2uiv; + PFNGLUNIFORM3DPROC Uniform3d; + PFNGLUNIFORM3DVPROC Uniform3dv; + PFNGLUNIFORM3FPROC Uniform3f; + PFNGLUNIFORM3FVPROC Uniform3fv; + PFNGLUNIFORM3IPROC Uniform3i; + PFNGLUNIFORM3IVPROC Uniform3iv; + PFNGLUNIFORM3UIPROC Uniform3ui; + PFNGLUNIFORM3UIVPROC Uniform3uiv; + PFNGLUNIFORM4DPROC Uniform4d; + PFNGLUNIFORM4DVPROC Uniform4dv; + PFNGLUNIFORM4FPROC Uniform4f; + PFNGLUNIFORM4FVPROC Uniform4fv; + PFNGLUNIFORM4IPROC Uniform4i; + PFNGLUNIFORM4IVPROC Uniform4iv; + PFNGLUNIFORM4UIPROC Uniform4ui; + PFNGLUNIFORM4UIVPROC Uniform4uiv; + PFNGLUNIFORMBLOCKBINDINGPROC UniformBlockBinding; + PFNGLUNIFORMMATRIX2DVPROC UniformMatrix2dv; + PFNGLUNIFORMMATRIX2FVPROC UniformMatrix2fv; + PFNGLUNIFORMMATRIX2X3DVPROC UniformMatrix2x3dv; + PFNGLUNIFORMMATRIX2X3FVPROC UniformMatrix2x3fv; + PFNGLUNIFORMMATRIX2X4DVPROC UniformMatrix2x4dv; + PFNGLUNIFORMMATRIX2X4FVPROC UniformMatrix2x4fv; + PFNGLUNIFORMMATRIX3DVPROC UniformMatrix3dv; + PFNGLUNIFORMMATRIX3FVPROC UniformMatrix3fv; + PFNGLUNIFORMMATRIX3X2DVPROC UniformMatrix3x2dv; + PFNGLUNIFORMMATRIX3X2FVPROC UniformMatrix3x2fv; + PFNGLUNIFORMMATRIX3X4DVPROC UniformMatrix3x4dv; + PFNGLUNIFORMMATRIX3X4FVPROC UniformMatrix3x4fv; + PFNGLUNIFORMMATRIX4DVPROC UniformMatrix4dv; + PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv; + PFNGLUNIFORMMATRIX4X2DVPROC UniformMatrix4x2dv; + PFNGLUNIFORMMATRIX4X2FVPROC UniformMatrix4x2fv; + PFNGLUNIFORMMATRIX4X3DVPROC UniformMatrix4x3dv; + PFNGLUNIFORMMATRIX4X3FVPROC UniformMatrix4x3fv; + PFNGLUNIFORMSUBROUTINESUIVPROC UniformSubroutinesuiv; + PFNGLUNMAPBUFFERPROC UnmapBuffer; + PFNGLUNMAPNAMEDBUFFERPROC UnmapNamedBuffer; + PFNGLUSEPROGRAMPROC UseProgram; + PFNGLUSEPROGRAMSTAGESPROC UseProgramStages; + PFNGLVALIDATEPROGRAMPROC ValidateProgram; + PFNGLVALIDATEPROGRAMPIPELINEPROC ValidateProgramPipeline; + PFNGLVERTEX2DPROC Vertex2d; + PFNGLVERTEX2DVPROC Vertex2dv; + PFNGLVERTEX2FPROC Vertex2f; + PFNGLVERTEX2FVPROC Vertex2fv; + PFNGLVERTEX2IPROC Vertex2i; + PFNGLVERTEX2IVPROC Vertex2iv; + PFNGLVERTEX2SPROC Vertex2s; + PFNGLVERTEX2SVPROC Vertex2sv; + PFNGLVERTEX3DPROC Vertex3d; + PFNGLVERTEX3DVPROC Vertex3dv; + PFNGLVERTEX3FPROC Vertex3f; + PFNGLVERTEX3FVPROC Vertex3fv; + PFNGLVERTEX3IPROC Vertex3i; + PFNGLVERTEX3IVPROC Vertex3iv; + PFNGLVERTEX3SPROC Vertex3s; + PFNGLVERTEX3SVPROC Vertex3sv; + PFNGLVERTEX4DPROC Vertex4d; + PFNGLVERTEX4DVPROC Vertex4dv; + PFNGLVERTEX4FPROC Vertex4f; + PFNGLVERTEX4FVPROC Vertex4fv; + PFNGLVERTEX4IPROC Vertex4i; + PFNGLVERTEX4IVPROC Vertex4iv; + PFNGLVERTEX4SPROC Vertex4s; + PFNGLVERTEX4SVPROC Vertex4sv; + PFNGLVERTEXARRAYATTRIBBINDINGPROC VertexArrayAttribBinding; + PFNGLVERTEXARRAYATTRIBFORMATPROC VertexArrayAttribFormat; + PFNGLVERTEXARRAYATTRIBIFORMATPROC VertexArrayAttribIFormat; + PFNGLVERTEXARRAYATTRIBLFORMATPROC VertexArrayAttribLFormat; + PFNGLVERTEXARRAYBINDINGDIVISORPROC VertexArrayBindingDivisor; + PFNGLVERTEXARRAYELEMENTBUFFERPROC VertexArrayElementBuffer; + PFNGLVERTEXARRAYVERTEXBUFFERPROC VertexArrayVertexBuffer; + PFNGLVERTEXARRAYVERTEXBUFFERSPROC VertexArrayVertexBuffers; + PFNGLVERTEXATTRIB1DPROC VertexAttrib1d; + PFNGLVERTEXATTRIB1DVPROC VertexAttrib1dv; + PFNGLVERTEXATTRIB1FPROC VertexAttrib1f; + PFNGLVERTEXATTRIB1FVPROC VertexAttrib1fv; + PFNGLVERTEXATTRIB1SPROC VertexAttrib1s; + PFNGLVERTEXATTRIB1SVPROC VertexAttrib1sv; + PFNGLVERTEXATTRIB2DPROC VertexAttrib2d; + PFNGLVERTEXATTRIB2DVPROC VertexAttrib2dv; + PFNGLVERTEXATTRIB2FPROC VertexAttrib2f; + PFNGLVERTEXATTRIB2FVPROC VertexAttrib2fv; + PFNGLVERTEXATTRIB2SPROC VertexAttrib2s; + PFNGLVERTEXATTRIB2SVPROC VertexAttrib2sv; + PFNGLVERTEXATTRIB3DPROC VertexAttrib3d; + PFNGLVERTEXATTRIB3DVPROC VertexAttrib3dv; + PFNGLVERTEXATTRIB3FPROC VertexAttrib3f; + PFNGLVERTEXATTRIB3FVPROC VertexAttrib3fv; + PFNGLVERTEXATTRIB3SPROC VertexAttrib3s; + PFNGLVERTEXATTRIB3SVPROC VertexAttrib3sv; + PFNGLVERTEXATTRIB4NBVPROC VertexAttrib4Nbv; + PFNGLVERTEXATTRIB4NIVPROC VertexAttrib4Niv; + PFNGLVERTEXATTRIB4NSVPROC VertexAttrib4Nsv; + PFNGLVERTEXATTRIB4NUBPROC VertexAttrib4Nub; + PFNGLVERTEXATTRIB4NUBVPROC VertexAttrib4Nubv; + PFNGLVERTEXATTRIB4NUIVPROC VertexAttrib4Nuiv; + PFNGLVERTEXATTRIB4NUSVPROC VertexAttrib4Nusv; + PFNGLVERTEXATTRIB4BVPROC VertexAttrib4bv; + PFNGLVERTEXATTRIB4DPROC VertexAttrib4d; + PFNGLVERTEXATTRIB4DVPROC VertexAttrib4dv; + PFNGLVERTEXATTRIB4FPROC VertexAttrib4f; + PFNGLVERTEXATTRIB4FVPROC VertexAttrib4fv; + PFNGLVERTEXATTRIB4IVPROC VertexAttrib4iv; + PFNGLVERTEXATTRIB4SPROC VertexAttrib4s; + PFNGLVERTEXATTRIB4SVPROC VertexAttrib4sv; + PFNGLVERTEXATTRIB4UBVPROC VertexAttrib4ubv; + PFNGLVERTEXATTRIB4UIVPROC VertexAttrib4uiv; + PFNGLVERTEXATTRIB4USVPROC VertexAttrib4usv; + PFNGLVERTEXATTRIBBINDINGPROC VertexAttribBinding; + PFNGLVERTEXATTRIBDIVISORPROC VertexAttribDivisor; + PFNGLVERTEXATTRIBFORMATPROC VertexAttribFormat; + PFNGLVERTEXATTRIBI1IPROC VertexAttribI1i; + PFNGLVERTEXATTRIBI1IVPROC VertexAttribI1iv; + PFNGLVERTEXATTRIBI1UIPROC VertexAttribI1ui; + PFNGLVERTEXATTRIBI1UIVPROC VertexAttribI1uiv; + PFNGLVERTEXATTRIBI2IPROC VertexAttribI2i; + PFNGLVERTEXATTRIBI2IVPROC VertexAttribI2iv; + PFNGLVERTEXATTRIBI2UIPROC VertexAttribI2ui; + PFNGLVERTEXATTRIBI2UIVPROC VertexAttribI2uiv; + PFNGLVERTEXATTRIBI3IPROC VertexAttribI3i; + PFNGLVERTEXATTRIBI3IVPROC VertexAttribI3iv; + PFNGLVERTEXATTRIBI3UIPROC VertexAttribI3ui; + PFNGLVERTEXATTRIBI3UIVPROC VertexAttribI3uiv; + PFNGLVERTEXATTRIBI4BVPROC VertexAttribI4bv; + PFNGLVERTEXATTRIBI4IPROC VertexAttribI4i; + PFNGLVERTEXATTRIBI4IVPROC VertexAttribI4iv; + PFNGLVERTEXATTRIBI4SVPROC VertexAttribI4sv; + PFNGLVERTEXATTRIBI4UBVPROC VertexAttribI4ubv; + PFNGLVERTEXATTRIBI4UIPROC VertexAttribI4ui; + PFNGLVERTEXATTRIBI4UIVPROC VertexAttribI4uiv; + PFNGLVERTEXATTRIBI4USVPROC VertexAttribI4usv; + PFNGLVERTEXATTRIBIFORMATPROC VertexAttribIFormat; + PFNGLVERTEXATTRIBIPOINTERPROC VertexAttribIPointer; + PFNGLVERTEXATTRIBL1DPROC VertexAttribL1d; + PFNGLVERTEXATTRIBL1DVPROC VertexAttribL1dv; + PFNGLVERTEXATTRIBL2DPROC VertexAttribL2d; + PFNGLVERTEXATTRIBL2DVPROC VertexAttribL2dv; + PFNGLVERTEXATTRIBL3DPROC VertexAttribL3d; + PFNGLVERTEXATTRIBL3DVPROC VertexAttribL3dv; + PFNGLVERTEXATTRIBL4DPROC VertexAttribL4d; + PFNGLVERTEXATTRIBL4DVPROC VertexAttribL4dv; + PFNGLVERTEXATTRIBLFORMATPROC VertexAttribLFormat; + PFNGLVERTEXATTRIBLPOINTERPROC VertexAttribLPointer; + PFNGLVERTEXATTRIBP1UIPROC VertexAttribP1ui; + PFNGLVERTEXATTRIBP1UIVPROC VertexAttribP1uiv; + PFNGLVERTEXATTRIBP2UIPROC VertexAttribP2ui; + PFNGLVERTEXATTRIBP2UIVPROC VertexAttribP2uiv; + PFNGLVERTEXATTRIBP3UIPROC VertexAttribP3ui; + PFNGLVERTEXATTRIBP3UIVPROC VertexAttribP3uiv; + PFNGLVERTEXATTRIBP4UIPROC VertexAttribP4ui; + PFNGLVERTEXATTRIBP4UIVPROC VertexAttribP4uiv; + PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer; + PFNGLVERTEXBINDINGDIVISORPROC VertexBindingDivisor; + PFNGLVERTEXP2UIPROC VertexP2ui; + PFNGLVERTEXP2UIVPROC VertexP2uiv; + PFNGLVERTEXP3UIPROC VertexP3ui; + PFNGLVERTEXP3UIVPROC VertexP3uiv; + PFNGLVERTEXP4UIPROC VertexP4ui; + PFNGLVERTEXP4UIVPROC VertexP4uiv; + PFNGLVERTEXPOINTERPROC VertexPointer; + PFNGLVIEWPORTPROC Viewport; + PFNGLVIEWPORTARRAYVPROC ViewportArrayv; + PFNGLVIEWPORTINDEXEDFPROC ViewportIndexedf; + PFNGLVIEWPORTINDEXEDFVPROC ViewportIndexedfv; + PFNGLWAITSYNCPROC WaitSync; + PFNGLWINDOWPOS2DPROC WindowPos2d; + PFNGLWINDOWPOS2DVPROC WindowPos2dv; + PFNGLWINDOWPOS2FPROC WindowPos2f; + PFNGLWINDOWPOS2FVPROC WindowPos2fv; + PFNGLWINDOWPOS2IPROC WindowPos2i; + PFNGLWINDOWPOS2IVPROC WindowPos2iv; + PFNGLWINDOWPOS2SPROC WindowPos2s; + PFNGLWINDOWPOS2SVPROC WindowPos2sv; + PFNGLWINDOWPOS3DPROC WindowPos3d; + PFNGLWINDOWPOS3DVPROC WindowPos3dv; + PFNGLWINDOWPOS3FPROC WindowPos3f; + PFNGLWINDOWPOS3FVPROC WindowPos3fv; + PFNGLWINDOWPOS3IPROC WindowPos3i; + PFNGLWINDOWPOS3IVPROC WindowPos3iv; + PFNGLWINDOWPOS3SPROC WindowPos3s; + PFNGLWINDOWPOS3SVPROC WindowPos3sv; +} GladGLContext; -GLAD_API_CALL int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr); -GLAD_API_CALL int gladLoadGL( GLADloadfunc load); -#ifdef __cplusplus -} -#endif -#endif - -/* Source */ -#ifdef GLAD_GL_IMPLEMENTATION -/** - * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 - */ -#include -#include -#include -#ifndef GLAD_IMPL_UTIL_C_ -#define GLAD_IMPL_UTIL_C_ +GLAD_API_CALL int gladLoadGLContextUserPtr(GladGLContext *context, GLADuserptrloadfunc load, void *userptr); +GLAD_API_CALL int gladLoadGLContext(GladGLContext *context, GLADloadfunc load); -#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; - - - -PFNGLACCUMPROC glad_glAccum = NULL; -PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram = NULL; -PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; -PFNGLALPHAFUNCPROC glad_glAlphaFunc = NULL; -PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident = NULL; -PFNGLARRAYELEMENTPROC glad_glArrayElement = NULL; -PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; -PFNGLBEGINPROC glad_glBegin = NULL; -PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL; -PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; -PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed = NULL; -PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL; -PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; -PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; -PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; -PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; -PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase = NULL; -PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange = NULL; -PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL; -PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL; -PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; -PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture = NULL; -PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures = NULL; -PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline = NULL; -PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; -PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL; -PFNGLBINDSAMPLERSPROC glad_glBindSamplers = NULL; -PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; -PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit = NULL; -PFNGLBINDTEXTURESPROC glad_glBindTextures = NULL; -PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback = NULL; -PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; -PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer = NULL; -PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers = NULL; -PFNGLBITMAPPROC glad_glBitmap = NULL; -PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; -PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; -PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; -PFNGLBLENDEQUATIONSEPARATEIPROC glad_glBlendEquationSeparatei = NULL; -PFNGLBLENDEQUATIONIPROC glad_glBlendEquationi = NULL; -PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; -PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; -PFNGLBLENDFUNCSEPARATEIPROC glad_glBlendFuncSeparatei = NULL; -PFNGLBLENDFUNCIPROC glad_glBlendFunci = NULL; -PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL; -PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer = NULL; -PFNGLBUFFERDATAPROC glad_glBufferData = NULL; -PFNGLBUFFERSTORAGEPROC glad_glBufferStorage = NULL; -PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; -PFNGLCALLLISTPROC glad_glCallList = NULL; -PFNGLCALLLISTSPROC glad_glCallLists = NULL; -PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; -PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus = NULL; -PFNGLCLAMPCOLORPROC glad_glClampColor = NULL; -PFNGLCLEARPROC glad_glClear = NULL; -PFNGLCLEARACCUMPROC glad_glClearAccum = 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; -PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL; -PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL; -PFNGLCLEARINDEXPROC glad_glClearIndex = NULL; -PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData = NULL; -PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData = 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; -PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; -PFNGLCLIPCONTROLPROC glad_glClipControl = NULL; -PFNGLCLIPPLANEPROC glad_glClipPlane = NULL; -PFNGLCOLOR3BPROC glad_glColor3b = NULL; -PFNGLCOLOR3BVPROC glad_glColor3bv = NULL; -PFNGLCOLOR3DPROC glad_glColor3d = NULL; -PFNGLCOLOR3DVPROC glad_glColor3dv = NULL; -PFNGLCOLOR3FPROC glad_glColor3f = NULL; -PFNGLCOLOR3FVPROC glad_glColor3fv = 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; -PFNGLCOLOR4BPROC glad_glColor4b = NULL; -PFNGLCOLOR4BVPROC glad_glColor4bv = NULL; -PFNGLCOLOR4DPROC glad_glColor4d = NULL; -PFNGLCOLOR4DVPROC glad_glColor4dv = NULL; -PFNGLCOLOR4FPROC glad_glColor4f = NULL; -PFNGLCOLOR4FVPROC glad_glColor4fv = NULL; -PFNGLCOLOR4IPROC glad_glColor4i = NULL; -PFNGLCOLOR4IVPROC glad_glColor4iv = NULL; -PFNGLCOLOR4SPROC glad_glColor4s = NULL; -PFNGLCOLOR4SVPROC glad_glColor4sv = NULL; -PFNGLCOLOR4UBPROC glad_glColor4ub = NULL; -PFNGLCOLOR4UBVPROC glad_glColor4ubv = NULL; -PFNGLCOLOR4UIPROC glad_glColor4ui = NULL; -PFNGLCOLOR4UIVPROC glad_glColor4uiv = NULL; -PFNGLCOLOR4USPROC glad_glColor4us = NULL; -PFNGLCOLOR4USVPROC glad_glColor4usv = NULL; -PFNGLCOLORMASKPROC glad_glColorMask = 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; -PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; -PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL; -PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; -PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; -PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D = NULL; -PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D = NULL; -PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D = NULL; -PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL; -PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData = NULL; -PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData = NULL; -PFNGLCOPYPIXELSPROC glad_glCopyPixels = NULL; -PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL; -PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; -PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL; -PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; -PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL; -PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D = NULL; -PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D = NULL; -PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D = NULL; -PFNGLCREATEBUFFERSPROC glad_glCreateBuffers = NULL; -PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers = NULL; -PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; -PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines = NULL; -PFNGLCREATEQUERIESPROC glad_glCreateQueries = NULL; -PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers = NULL; -PFNGLCREATESAMPLERSPROC glad_glCreateSamplers = NULL; -PFNGLCREATESHADERPROC glad_glCreateShader = NULL; -PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv = NULL; -PFNGLCREATETEXTURESPROC glad_glCreateTextures = NULL; -PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks = NULL; -PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays = NULL; -PFNGLCULLFACEPROC glad_glCullFace = NULL; -PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback = NULL; -PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl = NULL; -PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert = NULL; -PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; -PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; -PFNGLDELETELISTSPROC glad_glDeleteLists = NULL; -PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; -PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines = NULL; -PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; -PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; -PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL; -PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; -PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; -PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; -PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks = NULL; -PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL; -PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; -PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; -PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL; -PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv = NULL; -PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed = NULL; -PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL; -PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; -PFNGLDISABLEPROC glad_glDisable = NULL; -PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState = NULL; -PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib = NULL; -PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; -PFNGLDISABLEIPROC glad_glDisablei = NULL; -PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute = NULL; -PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect = NULL; -PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; -PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect = NULL; -PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL; -PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance = NULL; -PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL; -PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; -PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; -PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL; -PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect = NULL; -PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL; -PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance = NULL; -PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL; -PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance = NULL; -PFNGLDRAWPIXELSPROC glad_glDrawPixels = NULL; -PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; -PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL; -PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback = NULL; -PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced = NULL; -PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream = NULL; -PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced = NULL; -PFNGLEDGEFLAGPROC glad_glEdgeFlag = NULL; -PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer = NULL; -PFNGLEDGEFLAGVPROC glad_glEdgeFlagv = NULL; -PFNGLENABLEPROC glad_glEnable = NULL; -PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState = NULL; -PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib = NULL; -PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; -PFNGLENABLEIPROC glad_glEnablei = NULL; -PFNGLENDPROC glad_glEnd = NULL; -PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL; -PFNGLENDLISTPROC glad_glEndList = NULL; -PFNGLENDQUERYPROC glad_glEndQuery = NULL; -PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed = NULL; -PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; -PFNGLEVALCOORD1DPROC glad_glEvalCoord1d = NULL; -PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv = NULL; -PFNGLEVALCOORD1FPROC glad_glEvalCoord1f = NULL; -PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv = NULL; -PFNGLEVALCOORD2DPROC glad_glEvalCoord2d = NULL; -PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv = NULL; -PFNGLEVALCOORD2FPROC glad_glEvalCoord2f = NULL; -PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv = NULL; -PFNGLEVALMESH1PROC glad_glEvalMesh1 = NULL; -PFNGLEVALMESH2PROC glad_glEvalMesh2 = NULL; -PFNGLEVALPOINT1PROC glad_glEvalPoint1 = NULL; -PFNGLEVALPOINT2PROC glad_glEvalPoint2 = NULL; -PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer = NULL; -PFNGLFENCESYNCPROC glad_glFenceSync = NULL; -PFNGLFINISHPROC glad_glFinish = NULL; -PFNGLFLUSHPROC glad_glFlush = NULL; -PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; -PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange = NULL; -PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer = NULL; -PFNGLFOGCOORDDPROC glad_glFogCoordd = NULL; -PFNGLFOGCOORDDVPROC glad_glFogCoorddv = NULL; -PFNGLFOGCOORDFPROC glad_glFogCoordf = NULL; -PFNGLFOGCOORDFVPROC glad_glFogCoordfv = NULL; -PFNGLFOGFPROC glad_glFogf = NULL; -PFNGLFOGFVPROC glad_glFogfv = NULL; -PFNGLFOGIPROC glad_glFogi = NULL; -PFNGLFOGIVPROC glad_glFogiv = NULL; -PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri = NULL; -PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; -PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL; -PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL; -PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; -PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL; -PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; -PFNGLFRONTFACEPROC glad_glFrontFace = NULL; -PFNGLFRUSTUMPROC glad_glFrustum = NULL; -PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; -PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; -PFNGLGENLISTSPROC glad_glGenLists = NULL; -PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines = NULL; -PFNGLGENQUERIESPROC glad_glGenQueries = NULL; -PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; -PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL; -PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; -PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks = NULL; -PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; -PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; -PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap = NULL; -PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv = NULL; -PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; -PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName = NULL; -PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName = NULL; -PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv = NULL; -PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; -PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL; -PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL; -PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName = NULL; -PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL; -PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; -PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; -PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL; -PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; -PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL; -PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; -PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; -PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL; -PFNGLGETCLIPPLANEPROC glad_glGetClipPlane = NULL; -PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL; -PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage = NULL; -PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage = NULL; -PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog = NULL; -PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v = NULL; -PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL; -PFNGLGETERRORPROC glad_glGetError = NULL; -PFNGLGETFLOATI_VPROC glad_glGetFloati_v = NULL; -PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; -PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL; -PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; -PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; -PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv = NULL; -PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus = NULL; -PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL; -PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; -PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; -PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; -PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v = NULL; -PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ = NULL; -PFNGLGETLIGHTFVPROC glad_glGetLightfv = NULL; -PFNGLGETLIGHTIVPROC glad_glGetLightiv = NULL; -PFNGLGETMAPDVPROC glad_glGetMapdv = NULL; -PFNGLGETMAPFVPROC glad_glGetMapfv = NULL; -PFNGLGETMAPIVPROC glad_glGetMapiv = NULL; -PFNGLGETMATERIALFVPROC glad_glGetMaterialfv = NULL; -PFNGLGETMATERIALIVPROC glad_glGetMaterialiv = NULL; -PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL; -PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v = NULL; -PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv = NULL; -PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv = NULL; -PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData = NULL; -PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv = NULL; -PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv = NULL; -PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv = NULL; -PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel = NULL; -PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel = NULL; -PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv = NULL; -PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv = NULL; -PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv = NULL; -PFNGLGETPOINTERVPROC glad_glGetPointerv = NULL; -PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple = NULL; -PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary = NULL; -PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; -PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv = 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; -PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv = NULL; -PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv = NULL; -PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = 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; -PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL; -PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v = NULL; -PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; -PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; -PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; -PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv = NULL; -PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv = NULL; -PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL; -PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL; -PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; -PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL; -PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; -PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; -PFNGLGETSTRINGPROC glad_glGetString = NULL; -PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; -PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex = NULL; -PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation = NULL; -PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; -PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv = NULL; -PFNGLGETTEXENVIVPROC glad_glGetTexEnviv = NULL; -PFNGLGETTEXGENDVPROC glad_glGetTexGendv = NULL; -PFNGLGETTEXGENFVPROC glad_glGetTexGenfv = NULL; -PFNGLGETTEXGENIVPROC glad_glGetTexGeniv = NULL; -PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL; -PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; -PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; -PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL; -PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL; -PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; -PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; -PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage = NULL; -PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv = NULL; -PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv = NULL; -PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv = NULL; -PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv = NULL; -PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv = NULL; -PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv = NULL; -PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage = NULL; -PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; -PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v = NULL; -PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v = NULL; -PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv = NULL; -PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL; -PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL; -PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; -PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv = NULL; -PFNGLGETUNIFORMDVPROC glad_glGetUniformdv = NULL; -PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; -PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; -PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL; -PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv = NULL; -PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv = NULL; -PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv = NULL; -PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL; -PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL; -PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv = NULL; -PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; -PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL; -PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; -PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; -PFNGLGETNCOLORTABLEPROC glad_glGetnColorTable = NULL; -PFNGLGETNCOMPRESSEDTEXIMAGEPROC glad_glGetnCompressedTexImage = NULL; -PFNGLGETNCONVOLUTIONFILTERPROC glad_glGetnConvolutionFilter = NULL; -PFNGLGETNHISTOGRAMPROC glad_glGetnHistogram = NULL; -PFNGLGETNMAPDVPROC glad_glGetnMapdv = NULL; -PFNGLGETNMAPFVPROC glad_glGetnMapfv = NULL; -PFNGLGETNMAPIVPROC glad_glGetnMapiv = NULL; -PFNGLGETNMINMAXPROC glad_glGetnMinmax = NULL; -PFNGLGETNPIXELMAPFVPROC glad_glGetnPixelMapfv = NULL; -PFNGLGETNPIXELMAPUIVPROC glad_glGetnPixelMapuiv = NULL; -PFNGLGETNPIXELMAPUSVPROC glad_glGetnPixelMapusv = NULL; -PFNGLGETNPOLYGONSTIPPLEPROC glad_glGetnPolygonStipple = NULL; -PFNGLGETNSEPARABLEFILTERPROC glad_glGetnSeparableFilter = NULL; -PFNGLGETNTEXIMAGEPROC glad_glGetnTexImage = NULL; -PFNGLGETNUNIFORMDVPROC glad_glGetnUniformdv = NULL; -PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv = NULL; -PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv = NULL; -PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv = NULL; -PFNGLHINTPROC glad_glHint = NULL; -PFNGLINDEXMASKPROC glad_glIndexMask = NULL; -PFNGLINDEXPOINTERPROC glad_glIndexPointer = 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; -PFNGLINITNAMESPROC glad_glInitNames = NULL; -PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays = 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; -PFNGLISBUFFERPROC glad_glIsBuffer = NULL; -PFNGLISENABLEDPROC glad_glIsEnabled = NULL; -PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL; -PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; -PFNGLISLISTPROC glad_glIsList = NULL; -PFNGLISPROGRAMPROC glad_glIsProgram = NULL; -PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline = NULL; -PFNGLISQUERYPROC glad_glIsQuery = NULL; -PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; -PFNGLISSAMPLERPROC glad_glIsSampler = NULL; -PFNGLISSHADERPROC glad_glIsShader = NULL; -PFNGLISSYNCPROC glad_glIsSync = NULL; -PFNGLISTEXTUREPROC glad_glIsTexture = NULL; -PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback = NULL; -PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; -PFNGLLIGHTMODELFPROC glad_glLightModelf = NULL; -PFNGLLIGHTMODELFVPROC glad_glLightModelfv = NULL; -PFNGLLIGHTMODELIPROC glad_glLightModeli = NULL; -PFNGLLIGHTMODELIVPROC glad_glLightModeliv = NULL; -PFNGLLIGHTFPROC glad_glLightf = NULL; -PFNGLLIGHTFVPROC glad_glLightfv = NULL; -PFNGLLIGHTIPROC glad_glLighti = NULL; -PFNGLLIGHTIVPROC glad_glLightiv = NULL; -PFNGLLINESTIPPLEPROC glad_glLineStipple = NULL; -PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; -PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; -PFNGLLISTBASEPROC glad_glListBase = NULL; -PFNGLLOADIDENTITYPROC glad_glLoadIdentity = NULL; -PFNGLLOADMATRIXDPROC glad_glLoadMatrixd = NULL; -PFNGLLOADMATRIXFPROC glad_glLoadMatrixf = NULL; -PFNGLLOADNAMEPROC glad_glLoadName = NULL; -PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd = NULL; -PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf = NULL; -PFNGLLOGICOPPROC glad_glLogicOp = NULL; -PFNGLMAP1DPROC glad_glMap1d = NULL; -PFNGLMAP1FPROC glad_glMap1f = NULL; -PFNGLMAP2DPROC glad_glMap2d = NULL; -PFNGLMAP2FPROC glad_glMap2f = NULL; -PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL; -PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; -PFNGLMAPGRID1DPROC glad_glMapGrid1d = NULL; -PFNGLMAPGRID1FPROC glad_glMapGrid1f = NULL; -PFNGLMAPGRID2DPROC glad_glMapGrid2d = NULL; -PFNGLMAPGRID2FPROC glad_glMapGrid2f = NULL; -PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer = NULL; -PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange = NULL; -PFNGLMATERIALFPROC glad_glMaterialf = NULL; -PFNGLMATERIALFVPROC glad_glMaterialfv = NULL; -PFNGLMATERIALIPROC glad_glMateriali = NULL; -PFNGLMATERIALIVPROC glad_glMaterialiv = NULL; -PFNGLMATRIXMODEPROC glad_glMatrixMode = NULL; -PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier = NULL; -PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion = NULL; -PFNGLMINSAMPLESHADINGPROC glad_glMinSampleShading = NULL; -PFNGLMULTMATRIXDPROC glad_glMultMatrixd = NULL; -PFNGLMULTMATRIXFPROC glad_glMultMatrixf = NULL; -PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd = NULL; -PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf = NULL; -PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL; -PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect = NULL; -PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC glad_glMultiDrawArraysIndirectCount = NULL; -PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL; -PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL; -PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect = NULL; -PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC glad_glMultiDrawElementsIndirectCount = NULL; -PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d = NULL; -PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv = NULL; -PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f = NULL; -PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv = NULL; -PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i = NULL; -PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv = NULL; -PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s = NULL; -PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv = NULL; -PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d = NULL; -PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv = NULL; -PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f = NULL; -PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv = NULL; -PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i = NULL; -PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv = NULL; -PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s = NULL; -PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv = NULL; -PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d = NULL; -PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv = NULL; -PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f = NULL; -PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv = NULL; -PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i = NULL; -PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv = NULL; -PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s = NULL; -PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv = NULL; -PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d = NULL; -PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv = NULL; -PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f = NULL; -PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv = NULL; -PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i = NULL; -PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv = NULL; -PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s = NULL; -PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv = 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; -PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData = NULL; -PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage = NULL; -PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData = NULL; -PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer = NULL; -PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers = NULL; -PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri = NULL; -PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer = NULL; -PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer = NULL; -PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture = NULL; -PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer = NULL; -PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage = NULL; -PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample = NULL; -PFNGLNEWLISTPROC glad_glNewList = NULL; -PFNGLNORMAL3BPROC glad_glNormal3b = NULL; -PFNGLNORMAL3BVPROC glad_glNormal3bv = NULL; -PFNGLNORMAL3DPROC glad_glNormal3d = NULL; -PFNGLNORMAL3DVPROC glad_glNormal3dv = NULL; -PFNGLNORMAL3FPROC glad_glNormal3f = NULL; -PFNGLNORMAL3FVPROC glad_glNormal3fv = NULL; -PFNGLNORMAL3IPROC glad_glNormal3i = NULL; -PFNGLNORMAL3IVPROC glad_glNormal3iv = NULL; -PFNGLNORMAL3SPROC glad_glNormal3s = NULL; -PFNGLNORMAL3SVPROC glad_glNormal3sv = NULL; -PFNGLNORMALP3UIPROC glad_glNormalP3ui = NULL; -PFNGLNORMALP3UIVPROC glad_glNormalP3uiv = NULL; -PFNGLNORMALPOINTERPROC glad_glNormalPointer = NULL; -PFNGLOBJECTLABELPROC glad_glObjectLabel = NULL; -PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel = NULL; -PFNGLORTHOPROC glad_glOrtho = NULL; -PFNGLPASSTHROUGHPROC glad_glPassThrough = NULL; -PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv = NULL; -PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri = NULL; -PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback = NULL; -PFNGLPIXELMAPFVPROC glad_glPixelMapfv = NULL; -PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv = NULL; -PFNGLPIXELMAPUSVPROC glad_glPixelMapusv = NULL; -PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL; -PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; -PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf = NULL; -PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi = NULL; -PFNGLPIXELZOOMPROC glad_glPixelZoom = NULL; -PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL; -PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL; -PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL; -PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL; -PFNGLPOINTSIZEPROC glad_glPointSize = NULL; -PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL; -PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; -PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp = NULL; -PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple = NULL; -PFNGLPOPATTRIBPROC glad_glPopAttrib = NULL; -PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib = NULL; -PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup = NULL; -PFNGLPOPMATRIXPROC glad_glPopMatrix = NULL; -PFNGLPOPNAMEPROC glad_glPopName = NULL; -PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL; -PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures = NULL; -PFNGLPROGRAMBINARYPROC glad_glProgramBinary = NULL; -PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri = NULL; -PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d = NULL; -PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv = NULL; -PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f = NULL; -PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv = NULL; -PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i = NULL; -PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv = NULL; -PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui = NULL; -PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv = NULL; -PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d = NULL; -PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv = NULL; -PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f = NULL; -PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv = NULL; -PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i = NULL; -PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv = NULL; -PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui = NULL; -PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv = NULL; -PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d = NULL; -PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv = NULL; -PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f = NULL; -PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv = NULL; -PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i = NULL; -PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv = NULL; -PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui = NULL; -PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv = NULL; -PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d = NULL; -PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv = NULL; -PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f = NULL; -PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv = NULL; -PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i = NULL; -PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv = NULL; -PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui = NULL; -PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv = NULL; -PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv = NULL; -PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv = NULL; -PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv = NULL; -PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv = NULL; -PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv = NULL; -PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv = NULL; -PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv = NULL; -PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv = NULL; -PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv = NULL; -PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv = NULL; -PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv = NULL; -PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv = NULL; -PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv = NULL; -PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv = NULL; -PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv = NULL; -PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv = NULL; -PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv = NULL; -PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv = NULL; -PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL; -PFNGLPUSHATTRIBPROC glad_glPushAttrib = NULL; -PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib = NULL; -PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup = NULL; -PFNGLPUSHMATRIXPROC glad_glPushMatrix = NULL; -PFNGLPUSHNAMEPROC glad_glPushName = NULL; -PFNGLQUERYCOUNTERPROC glad_glQueryCounter = 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; -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; -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; -PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; -PFNGLREADPIXELSPROC glad_glReadPixels = NULL; -PFNGLREADNPIXELSPROC glad_glReadnPixels = 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; -PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL; -PFNGLRENDERMODEPROC glad_glRenderMode = NULL; -PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; -PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; -PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL; -PFNGLROTATEDPROC glad_glRotated = NULL; -PFNGLROTATEFPROC glad_glRotatef = NULL; -PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; -PFNGLSAMPLEMASKIPROC glad_glSampleMaski = 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; -PFNGLSCISSORPROC glad_glScissor = NULL; -PFNGLSCISSORARRAYVPROC glad_glScissorArrayv = NULL; -PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed = NULL; -PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv = NULL; -PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b = NULL; -PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv = NULL; -PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d = NULL; -PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv = NULL; -PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f = NULL; -PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv = NULL; -PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i = NULL; -PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv = NULL; -PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s = NULL; -PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv = NULL; -PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub = NULL; -PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv = NULL; -PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui = NULL; -PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv = NULL; -PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us = NULL; -PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv = NULL; -PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui = NULL; -PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv = NULL; -PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer = NULL; -PFNGLSELECTBUFFERPROC glad_glSelectBuffer = NULL; -PFNGLSHADEMODELPROC glad_glShadeModel = NULL; -PFNGLSHADERBINARYPROC glad_glShaderBinary = NULL; -PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; -PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding = NULL; -PFNGLSPECIALIZESHADERPROC glad_glSpecializeShader = NULL; -PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; -PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; -PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; -PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; -PFNGLSTENCILOPPROC glad_glStencilOp = NULL; -PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; -PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL; -PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange = NULL; -PFNGLTEXCOORD1DPROC glad_glTexCoord1d = NULL; -PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv = NULL; -PFNGLTEXCOORD1FPROC glad_glTexCoord1f = NULL; -PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv = NULL; -PFNGLTEXCOORD1IPROC glad_glTexCoord1i = NULL; -PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv = NULL; -PFNGLTEXCOORD1SPROC glad_glTexCoord1s = NULL; -PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv = NULL; -PFNGLTEXCOORD2DPROC glad_glTexCoord2d = NULL; -PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv = NULL; -PFNGLTEXCOORD2FPROC glad_glTexCoord2f = NULL; -PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv = NULL; -PFNGLTEXCOORD2IPROC glad_glTexCoord2i = NULL; -PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv = NULL; -PFNGLTEXCOORD2SPROC glad_glTexCoord2s = NULL; -PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv = NULL; -PFNGLTEXCOORD3DPROC glad_glTexCoord3d = NULL; -PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv = NULL; -PFNGLTEXCOORD3FPROC glad_glTexCoord3f = NULL; -PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv = NULL; -PFNGLTEXCOORD3IPROC glad_glTexCoord3i = NULL; -PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv = NULL; -PFNGLTEXCOORD3SPROC glad_glTexCoord3s = NULL; -PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv = NULL; -PFNGLTEXCOORD4DPROC glad_glTexCoord4d = NULL; -PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv = NULL; -PFNGLTEXCOORD4FPROC glad_glTexCoord4f = NULL; -PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv = NULL; -PFNGLTEXCOORD4IPROC glad_glTexCoord4i = NULL; -PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv = NULL; -PFNGLTEXCOORD4SPROC glad_glTexCoord4s = NULL; -PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv = 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; -PFNGLTEXENVFPROC glad_glTexEnvf = NULL; -PFNGLTEXENVFVPROC glad_glTexEnvfv = NULL; -PFNGLTEXENVIPROC glad_glTexEnvi = NULL; -PFNGLTEXENVIVPROC glad_glTexEnviv = 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; -PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL; -PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; -PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL; -PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; -PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample = NULL; -PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL; -PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL; -PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; -PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; -PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; -PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; -PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D = NULL; -PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D = NULL; -PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample = NULL; -PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D = NULL; -PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample = NULL; -PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL; -PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; -PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL; -PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier = NULL; -PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer = NULL; -PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange = NULL; -PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv = NULL; -PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv = NULL; -PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf = NULL; -PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv = NULL; -PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri = NULL; -PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv = NULL; -PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D = NULL; -PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D = NULL; -PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample = NULL; -PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D = NULL; -PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample = NULL; -PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D = NULL; -PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D = NULL; -PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D = NULL; -PFNGLTEXTUREVIEWPROC glad_glTextureView = NULL; -PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase = NULL; -PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange = NULL; -PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; -PFNGLTRANSLATEDPROC glad_glTranslated = NULL; -PFNGLTRANSLATEFPROC glad_glTranslatef = NULL; -PFNGLUNIFORM1DPROC glad_glUniform1d = NULL; -PFNGLUNIFORM1DVPROC glad_glUniform1dv = NULL; -PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; -PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; -PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; -PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; -PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL; -PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL; -PFNGLUNIFORM2DPROC glad_glUniform2d = NULL; -PFNGLUNIFORM2DVPROC glad_glUniform2dv = NULL; -PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; -PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; -PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; -PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; -PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL; -PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL; -PFNGLUNIFORM3DPROC glad_glUniform3d = NULL; -PFNGLUNIFORM3DVPROC glad_glUniform3dv = NULL; -PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; -PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; -PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; -PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; -PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL; -PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL; -PFNGLUNIFORM4DPROC glad_glUniform4d = NULL; -PFNGLUNIFORM4DVPROC glad_glUniform4dv = NULL; -PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; -PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; -PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; -PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; -PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; -PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; -PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL; -PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv = NULL; -PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = 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; -PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv = NULL; -PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL; -PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv = NULL; -PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL; -PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv = NULL; -PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; -PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv = NULL; -PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL; -PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv = NULL; -PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL; -PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv = NULL; -PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL; -PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer = NULL; -PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; -PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages = NULL; -PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; -PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline = NULL; -PFNGLVERTEX2DPROC glad_glVertex2d = NULL; -PFNGLVERTEX2DVPROC glad_glVertex2dv = NULL; -PFNGLVERTEX2FPROC glad_glVertex2f = NULL; -PFNGLVERTEX2FVPROC glad_glVertex2fv = NULL; -PFNGLVERTEX2IPROC glad_glVertex2i = NULL; -PFNGLVERTEX2IVPROC glad_glVertex2iv = NULL; -PFNGLVERTEX2SPROC glad_glVertex2s = NULL; -PFNGLVERTEX2SVPROC glad_glVertex2sv = NULL; -PFNGLVERTEX3DPROC glad_glVertex3d = NULL; -PFNGLVERTEX3DVPROC glad_glVertex3dv = NULL; -PFNGLVERTEX3FPROC glad_glVertex3f = NULL; -PFNGLVERTEX3FVPROC glad_glVertex3fv = NULL; -PFNGLVERTEX3IPROC glad_glVertex3i = NULL; -PFNGLVERTEX3IVPROC glad_glVertex3iv = NULL; -PFNGLVERTEX3SPROC glad_glVertex3s = NULL; -PFNGLVERTEX3SVPROC glad_glVertex3sv = NULL; -PFNGLVERTEX4DPROC glad_glVertex4d = NULL; -PFNGLVERTEX4DVPROC glad_glVertex4dv = NULL; -PFNGLVERTEX4FPROC glad_glVertex4f = NULL; -PFNGLVERTEX4FVPROC glad_glVertex4fv = NULL; -PFNGLVERTEX4IPROC glad_glVertex4i = NULL; -PFNGLVERTEX4IVPROC glad_glVertex4iv = NULL; -PFNGLVERTEX4SPROC glad_glVertex4s = NULL; -PFNGLVERTEX4SVPROC glad_glVertex4sv = NULL; -PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding = NULL; -PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat = NULL; -PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat = NULL; -PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat = NULL; -PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor = NULL; -PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer = NULL; -PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer = NULL; -PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers = NULL; -PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL; -PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL; -PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL; -PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL; -PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL; -PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL; -PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL; -PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL; -PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL; -PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL; -PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL; -PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL; -PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL; -PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL; -PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL; -PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL; -PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL; -PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL; -PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL; -PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL; -PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL; -PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL; -PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL; -PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL; -PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL; -PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL; -PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL; -PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL; -PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL; -PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL; -PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL; -PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL; -PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL; -PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL; -PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL; -PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL; -PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding = NULL; -PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL; -PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat = NULL; -PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL; -PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL; -PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL; -PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL; -PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL; -PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL; -PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL; -PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL; -PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL; -PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL; -PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL; -PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL; -PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL; -PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL; -PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL; -PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL; -PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL; -PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; -PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; -PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL; -PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat = NULL; -PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; -PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d = NULL; -PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv = NULL; -PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d = NULL; -PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv = NULL; -PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d = NULL; -PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv = NULL; -PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d = NULL; -PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv = NULL; -PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat = NULL; -PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer = 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; -PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; -PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor = 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; -PFNGLVIEWPORTPROC glad_glViewport = NULL; -PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv = NULL; -PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf = NULL; -PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv = NULL; -PFNGLWAITSYNCPROC glad_glWaitSync = NULL; -PFNGLWINDOWPOS2DPROC glad_glWindowPos2d = NULL; -PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv = NULL; -PFNGLWINDOWPOS2FPROC glad_glWindowPos2f = NULL; -PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv = NULL; -PFNGLWINDOWPOS2IPROC glad_glWindowPos2i = NULL; -PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv = NULL; -PFNGLWINDOWPOS2SPROC glad_glWindowPos2s = NULL; -PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv = NULL; -PFNGLWINDOWPOS3DPROC glad_glWindowPos3d = NULL; -PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv = NULL; -PFNGLWINDOWPOS3FPROC glad_glWindowPos3f = NULL; -PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv = NULL; -PFNGLWINDOWPOS3IPROC glad_glWindowPos3i = NULL; -PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv = NULL; -PFNGLWINDOWPOS3SPROC glad_glWindowPos3s = NULL; -PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv = 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_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; -} -#if 0 // This function is unused [Seb] -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; -} -#endif - -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; -#if 0 // This trick to deal with the function being unused triggers annoying warning in Visual Studio, so ifdef out [Seb] - GLAD_UNUSED(glad_gl_has_extension); #endif - 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; - - - - return version; -} - - -int gladLoadGL( GLADloadfunc load) { - return gladLoadGLUserPtr( glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); -} - - - - - - -#ifdef __cplusplus -} #endif - -#endif /* GLAD_GL_IMPLEMENTATION */ diff --git a/mplot/glad/khrplatform.h b/mplot/glad/khrplatform.h new file mode 100644 index 00000000..01646449 --- /dev/null +++ b/mplot/glad/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_ */ From 44c4bfd6686061cf53568ef934577182245b0dd7 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 6 Mar 2026 14:47:44 +0000 Subject: [PATCH 020/106] And that gets the fonts into a library --- examples/CMakeLists.txt | 2 +- mplot/CMakeLists.txt | 4 ++ mplot/VisualFace.h | 137 +--------------------------------------- mplot/VisualFaceAsm.cpp | 106 +++++++++++++++++++++++++++++++ mplot/VisualFaceAsm.h | 36 +++++++++++ 5 files changed, 149 insertions(+), 136 deletions(-) create mode 100644 mplot/VisualFaceAsm.cpp create mode 100644 mplot/VisualFaceAsm.h diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index c59b9bab..d71b59d4 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -67,7 +67,7 @@ target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE ${PROJECT_SOURCE_DIR}/maths/sm/geometry ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra ${PROJECT_SOURCE_DIR}/maths/sm/vvec) -target_link_libraries(helloworld OpenGL::GL glfw Freetype::Freetype glad) +target_link_libraries(helloworld OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) add_executable(rod rod.cpp) target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} diff --git a/mplot/CMakeLists.txt b/mplot/CMakeLists.txt index f9b065cf..76800fa5 100644 --- a/mplot/CMakeLists.txt +++ b/mplot/CMakeLists.txt @@ -100,6 +100,10 @@ if(WIN32) add_subdirectory(fonts) endif() +# Build a small library containing the mathplot font binaries +include_directories(BEFORE ${PROJECT_SOURCE_DIR}) +add_library(mplot_fontdata VisualFaceAsm.cpp) + # There are also headers in sub directories add_subdirectory(gl) # GL common and compute code add_subdirectory(glad) # GLAD header library diff --git a/mplot/VisualFace.h b/mplot/VisualFace.h index 3f7149ca..07107d0d 100644 --- a/mplot/VisualFace.h +++ b/mplot/VisualFace.h @@ -28,140 +28,7 @@ module; #include -/* - * The following inline assembly incorporates Vera.ttf and friends *into the binary*. We - * have different code for Linux and Mac. Both tested only on Intel CPUs. - */ - -#ifdef __linux__ - -# ifdef __aarch64__ - -// "a", @progbits isn't liked by pi/arm, but "a", %progbits DOES seem to be necessary -asm("\n.pushsection vera_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/Vera.ttf\"\n.popsection\n"); -asm("\n.pushsection verait_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraIt.ttf\"\n.popsection\n"); -asm("\n.pushsection verabd_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBd.ttf\"\n.popsection\n"); -asm("\n.pushsection verabi_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBI.ttf\"\n.popsection\n"); -asm("\n.pushsection veramono_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMono.ttf\"\n.popsection\n"); -asm("\n.pushsection veramoit_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoIt.ttf\"\n.popsection\n"); -asm("\n.pushsection veramobd_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBd.ttf\"\n.popsection\n"); -asm("\n.pushsection veramobi_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBI.ttf\"\n.popsection\n"); -asm("\n.pushsection verase_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSe.ttf\"\n.popsection\n"); -asm("\n.pushsection verasebd_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSeBd.ttf\"\n.popsection\n"); - -// DejaVu Sans allows for Greek symbols and will be the default -asm("\n.pushsection dvsans_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans.ttf\"\n.popsection\n"); -asm("\n.pushsection dvsansit_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Oblique.ttf\"\n.popsection\n"); -asm("\n.pushsection dvsansbd_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Bold.ttf\"\n.popsection\n"); -asm("\n.pushsection dvsansbi_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-BoldOblique.ttf\"\n.popsection\n"); - -# else - -// "a", @progbits means 'allocatable section containing type data'. It seems not to be strictly necessary. -asm("\n.pushsection vera_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/Vera.ttf\"\n.popsection\n"); -asm("\n.pushsection verait_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraIt.ttf\"\n.popsection\n"); -asm("\n.pushsection verabd_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBd.ttf\"\n.popsection\n"); -asm("\n.pushsection verabi_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBI.ttf\"\n.popsection\n"); -asm("\n.pushsection veramono_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMono.ttf\"\n.popsection\n"); -asm("\n.pushsection veramoit_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoIt.ttf\"\n.popsection\n"); -asm("\n.pushsection veramobd_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBd.ttf\"\n.popsection\n"); -asm("\n.pushsection veramobi_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBI.ttf\"\n.popsection\n"); -asm("\n.pushsection verase_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSe.ttf\"\n.popsection\n"); -asm("\n.pushsection verasebd_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSeBd.ttf\"\n.popsection\n"); - -// DejaVu Sans allows for Greek symbols and will be the default -asm("\n.pushsection dvsans_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans.ttf\"\n.popsection\n"); -asm("\n.pushsection dvsansit_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Oblique.ttf\"\n.popsection\n"); -asm("\n.pushsection dvsansbd_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Bold.ttf\"\n.popsection\n"); -asm("\n.pushsection dvsansbi_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-BoldOblique.ttf\"\n.popsection\n"); - -#endif - -#elif defined __APPLE__ - -// On Mac, we need a different incantation to use .incbin -asm("\t.global ___start_vera_ttf\n\t.global ___stop_vera_ttf\n___start_vera_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/Vera.ttf\"\n___stop_vera_ttf:\n"); -asm("\t.global ___start_verait_ttf\n\t.global ___stop_verait_ttf\n___start_verait_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraIt.ttf\"\n___stop_verait_ttf:\n"); -asm("\t.global ___start_verabd_ttf\n\t.global ___stop_verabd_ttf\n___start_verabd_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBd.ttf\"\n___stop_verabd_ttf:\n"); -asm("\t.global ___start_verabi_ttf\n\t.global ___stop_verabi_ttf\n___start_verabi_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBI.ttf\"\n___stop_verabi_ttf:\n"); -asm("\t.global ___start_veramono_ttf\n\t.global ___stop_veramono_ttf\n___start_veramono_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMono.ttf\"\n___stop_veramono_ttf:\n"); -asm("\t.global ___start_veramoit_ttf\n\t.global ___stop_veramoit_ttf\n___start_veramoit_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoIt.ttf\"\n___stop_veramoit_ttf:\n"); -asm("\t.global ___start_veramobd_ttf\n\t.global ___stop_veramobd_ttf\n___start_veramobd_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBd.ttf\"\n___stop_veramobd_ttf:\n"); -asm("\t.global ___start_veramobi_ttf\n\t.global ___stop_veramobi_ttf\n___start_veramobi_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBI.ttf\"\n___stop_veramobi_ttf:\n"); -asm("\t.global ___start_verase_ttf\n\t.global ___stop_verase_ttf\n___start_verase_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSe.ttf\"\n___stop_verase_ttf:\n"); -asm("\t.global ___start_verasebd_ttf\n\t.global ___stop_verasebd_ttf\n___start_verasebd_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSeBd.ttf\"\n___stop_verasebd_ttf:\n"); - -asm("\t.global ___start_dvsans_ttf\n\t.global ___stop_dvsans_ttf\n___start_dvsans_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans.ttf\"\n___stop_dvsans_ttf:\n"); -asm("\t.global ___start_dvsansit_ttf\n\t.global ___stop_dvsansit_ttf\n___start_dvsansit_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Oblique.ttf\"\n___stop_dvsansit_ttf:\n"); -asm("\t.global ___start_dvsansbd_ttf\n\t.global ___stop_dvsansbd_ttf\n___start_dvsansbd_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Bold.ttf\"\n___stop_dvsansbd_ttf:\n"); -asm("\t.global ___start_dvsansbi_ttf\n\t.global ___stop_dvsansbi_ttf\n___start_dvsansbi_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-BoldOblique.ttf\"\n___stop_dvsansbi_ttf:\n"); - -#elif defined _MSC_VER - -# include // Includes vera fonts AND DejaVu fonts. -# include - -#elif defined _mplot_WIN__INCBIN // Define this only for parsing this file with the incbin executable to create verafonts.h - -// Visual Studio doesn't allow __asm{} calls in C__ code anymore, so try Dale Weiler's incbin.h -#define INCBIN_PREFIX vf_ -#include -INCBIN(vera, "./fonts/ttf-bitstream-vera/Vera.ttf"); -INCBIN(verait, "./fonts/ttf-bitstream-vera/VeraIt.ttf"); -INCBIN(verabd, "./fonts/ttf-bitstream-vera/VeraBd.ttf"); -INCBIN(verabi, "./fonts/ttf-bitstream-vera/VeraBI.ttf"); -INCBIN(veramono, "./fonts/ttf-bitstream-vera/VeraMono.ttf"); -INCBIN(veramoit, "./fonts/ttf-bitstream-vera/VeraMoIt.ttf"); -INCBIN(veramobd, "./fonts/ttf-bitstream-vera/VeraMoBd.ttf"); -INCBIN(veramobi, "./fonts/ttf-bitstream-vera/VeraMoBI.ttf"); -INCBIN(verase, "./fonts/ttf-bitstream-vera/VeraSe.ttf"); -INCBIN(verasebd, "./fonts/ttf-bitstream-vera/VeraSeBd.ttf"); -// These translation units now have three symbols, eg: -// extern const unsigned char vf_veraData[]; -// extern const unsigned char *const vf_veraEnd; -// extern const unsigned int vf_veraSize; - -INCBIN(dvsans, "./fonts/dejavu/DejaVuSans.ttf"); -INCBIN(dvsansit, "./fonts/dejavu/DejaVuSans-Oblique.ttf"); -INCBIN(dvsansbd, "./fonts/dejavu/DejaVuSans-Bold.ttf"); -INCBIN(dvsansbi, "./fonts/dejavu/DejaVuSans-BoldOblique.ttf"); - -#else -# error "Inline assembly code for including truetype fonts in the binary only work on Linux/MacOS (and then, probably only on Intel compatible compilers. Sorry about that!" -#endif - -// These external pointers are set up by the inline assembly above -#ifndef _MSC_VER -extern const char __start_verabd_ttf[]; -extern const char __stop_verabd_ttf[]; -extern const char __start_verabi_ttf[]; -extern const char __stop_verabi_ttf[]; -extern const char __start_verait_ttf[]; -extern const char __stop_verait_ttf[]; -extern const char __start_veramobd_ttf[]; -extern const char __stop_veramobd_ttf[]; -extern const char __start_veramobi_ttf[]; -extern const char __stop_veramobi_ttf[]; -extern const char __start_veramoit_ttf[]; -extern const char __stop_veramoit_ttf[]; -extern const char __start_veramono_ttf[]; -extern const char __stop_veramono_ttf[]; -extern const char __start_verasebd_ttf[]; -extern const char __stop_verasebd_ttf[]; -extern const char __start_verase_ttf[]; -extern const char __stop_verase_ttf[]; -extern const char __start_vera_ttf[]; -extern const char __stop_vera_ttf[]; - -extern const char __start_dvsans_ttf[]; -extern const char __stop_dvsans_ttf[]; -extern const char __start_dvsansit_ttf[]; -extern const char __stop_dvsansit_ttf[]; -extern const char __start_dvsansbd_ttf[]; -extern const char __stop_dvsansbd_ttf[]; -extern const char __start_dvsansbi_ttf[]; -extern const char __stop_dvsansbi_ttf[]; -#endif +#include /* * Module starts here @@ -179,7 +46,7 @@ export namespace mplot::visgl { struct VisualFace { - VisualFace () {} + VisualFace () { std::cout << "meaningless function: " << meaningless::function() << std::endl; } /*! * Construct with a mplot::VisualFont \a _font, which specifies a supported * font (one which we can legally include in the source code without paying any licence fees, diff --git a/mplot/VisualFaceAsm.cpp b/mplot/VisualFaceAsm.cpp new file mode 100644 index 00000000..80ccc77e --- /dev/null +++ b/mplot/VisualFaceAsm.cpp @@ -0,0 +1,106 @@ +/* + * The following inline assembly incorporates Vera.ttf and friends *into the binary*. We + * have different code for Linux and Mac. Both tested only on Intel CPUs. + */ + +#ifdef __linux__ + +# ifdef __aarch64__ + +// "a", @progbits isn't liked by pi/arm, but "a", %progbits DOES seem to be necessary +asm("\n.pushsection vera_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/Vera.ttf\"\n.popsection\n"); +asm("\n.pushsection verait_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraIt.ttf\"\n.popsection\n"); +asm("\n.pushsection verabd_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBd.ttf\"\n.popsection\n"); +asm("\n.pushsection verabi_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBI.ttf\"\n.popsection\n"); +asm("\n.pushsection veramono_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMono.ttf\"\n.popsection\n"); +asm("\n.pushsection veramoit_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoIt.ttf\"\n.popsection\n"); +asm("\n.pushsection veramobd_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBd.ttf\"\n.popsection\n"); +asm("\n.pushsection veramobi_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBI.ttf\"\n.popsection\n"); +asm("\n.pushsection verase_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSe.ttf\"\n.popsection\n"); +asm("\n.pushsection verasebd_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSeBd.ttf\"\n.popsection\n"); + +// DejaVu Sans allows for Greek symbols and will be the default +asm("\n.pushsection dvsans_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans.ttf\"\n.popsection\n"); +asm("\n.pushsection dvsansit_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Oblique.ttf\"\n.popsection\n"); +asm("\n.pushsection dvsansbd_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Bold.ttf\"\n.popsection\n"); +asm("\n.pushsection dvsansbi_ttf, \"a\", %progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-BoldOblique.ttf\"\n.popsection\n"); + +# else + +// "a", @progbits means 'allocatable section containing type data'. It seems not to be strictly necessary. +asm("\n.pushsection vera_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/Vera.ttf\"\n.popsection\n"); +asm("\n.pushsection verait_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraIt.ttf\"\n.popsection\n"); +asm("\n.pushsection verabd_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBd.ttf\"\n.popsection\n"); +asm("\n.pushsection verabi_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBI.ttf\"\n.popsection\n"); +asm("\n.pushsection veramono_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMono.ttf\"\n.popsection\n"); +asm("\n.pushsection veramoit_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoIt.ttf\"\n.popsection\n"); +asm("\n.pushsection veramobd_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBd.ttf\"\n.popsection\n"); +asm("\n.pushsection veramobi_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBI.ttf\"\n.popsection\n"); +asm("\n.pushsection verase_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSe.ttf\"\n.popsection\n"); +asm("\n.pushsection verasebd_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSeBd.ttf\"\n.popsection\n"); + +// DejaVu Sans allows for Greek symbols and will be the default +asm("\n.pushsection dvsans_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans.ttf\"\n.popsection\n"); +asm("\n.pushsection dvsansit_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Oblique.ttf\"\n.popsection\n"); +asm("\n.pushsection dvsansbd_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Bold.ttf\"\n.popsection\n"); +asm("\n.pushsection dvsansbi_ttf, \"a\", @progbits\n.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-BoldOblique.ttf\"\n.popsection\n"); + +#endif + +#elif defined __APPLE__ + +// On Mac, we need a different incantation to use .incbin +asm("\t.global ___start_vera_ttf\n\t.global ___stop_vera_ttf\n___start_vera_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/Vera.ttf\"\n___stop_vera_ttf:\n"); +asm("\t.global ___start_verait_ttf\n\t.global ___stop_verait_ttf\n___start_verait_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraIt.ttf\"\n___stop_verait_ttf:\n"); +asm("\t.global ___start_verabd_ttf\n\t.global ___stop_verabd_ttf\n___start_verabd_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBd.ttf\"\n___stop_verabd_ttf:\n"); +asm("\t.global ___start_verabi_ttf\n\t.global ___stop_verabi_ttf\n___start_verabi_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraBI.ttf\"\n___stop_verabi_ttf:\n"); +asm("\t.global ___start_veramono_ttf\n\t.global ___stop_veramono_ttf\n___start_veramono_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMono.ttf\"\n___stop_veramono_ttf:\n"); +asm("\t.global ___start_veramoit_ttf\n\t.global ___stop_veramoit_ttf\n___start_veramoit_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoIt.ttf\"\n___stop_veramoit_ttf:\n"); +asm("\t.global ___start_veramobd_ttf\n\t.global ___stop_veramobd_ttf\n___start_veramobd_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBd.ttf\"\n___stop_veramobd_ttf:\n"); +asm("\t.global ___start_veramobi_ttf\n\t.global ___stop_veramobi_ttf\n___start_veramobi_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraMoBI.ttf\"\n___stop_veramobi_ttf:\n"); +asm("\t.global ___start_verase_ttf\n\t.global ___stop_verase_ttf\n___start_verase_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSe.ttf\"\n___stop_verase_ttf:\n"); +asm("\t.global ___start_verasebd_ttf\n\t.global ___stop_verasebd_ttf\n___start_verasebd_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/ttf-bitstream-vera/VeraSeBd.ttf\"\n___stop_verasebd_ttf:\n"); + +asm("\t.global ___start_dvsans_ttf\n\t.global ___stop_dvsans_ttf\n___start_dvsans_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans.ttf\"\n___stop_dvsans_ttf:\n"); +asm("\t.global ___start_dvsansit_ttf\n\t.global ___stop_dvsansit_ttf\n___start_dvsansit_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Oblique.ttf\"\n___stop_dvsansit_ttf:\n"); +asm("\t.global ___start_dvsansbd_ttf\n\t.global ___stop_dvsansbd_ttf\n___start_dvsansbd_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-Bold.ttf\"\n___stop_dvsansbd_ttf:\n"); +asm("\t.global ___start_dvsansbi_ttf\n\t.global ___stop_dvsansbi_ttf\n___start_dvsansbi_ttf:\n\t.incbin \"" MPLOT_FONTS_DIR "/dejavu/DejaVuSans-BoldOblique.ttf\"\n___stop_dvsansbi_ttf:\n"); + +#elif defined _MSC_VER + +# include // Includes vera fonts AND DejaVu fonts. +# include + +#elif defined _mplot_WIN__INCBIN // Define this only for parsing this file with the incbin executable to create verafonts.h + +// Visual Studio doesn't allow __asm{} calls in C__ code anymore, so try Dale Weiler's incbin.h +#define INCBIN_PREFIX vf_ +#include +INCBIN(vera, "./fonts/ttf-bitstream-vera/Vera.ttf"); +INCBIN(verait, "./fonts/ttf-bitstream-vera/VeraIt.ttf"); +INCBIN(verabd, "./fonts/ttf-bitstream-vera/VeraBd.ttf"); +INCBIN(verabi, "./fonts/ttf-bitstream-vera/VeraBI.ttf"); +INCBIN(veramono, "./fonts/ttf-bitstream-vera/VeraMono.ttf"); +INCBIN(veramoit, "./fonts/ttf-bitstream-vera/VeraMoIt.ttf"); +INCBIN(veramobd, "./fonts/ttf-bitstream-vera/VeraMoBd.ttf"); +INCBIN(veramobi, "./fonts/ttf-bitstream-vera/VeraMoBI.ttf"); +INCBIN(verase, "./fonts/ttf-bitstream-vera/VeraSe.ttf"); +INCBIN(verasebd, "./fonts/ttf-bitstream-vera/VeraSeBd.ttf"); +// These translation units now have three symbols, eg: +// extern const unsigned char vf_veraData[]; +// extern const unsigned char *const vf_veraEnd; +// extern const unsigned int vf_veraSize; + +INCBIN(dvsans, "./fonts/dejavu/DejaVuSans.ttf"); +INCBIN(dvsansit, "./fonts/dejavu/DejaVuSans-Oblique.ttf"); +INCBIN(dvsansbd, "./fonts/dejavu/DejaVuSans-Bold.ttf"); +INCBIN(dvsansbi, "./fonts/dejavu/DejaVuSans-BoldOblique.ttf"); + +#else +# error "Inline assembly code for including truetype fonts in the binary only work on Linux/MacOS (and then, probably only on Intel compatible compilers. Sorry about that!" +#endif + +#include + +// Dummy function +int meaningless::function() { return 42; } diff --git a/mplot/VisualFaceAsm.h b/mplot/VisualFaceAsm.h new file mode 100644 index 00000000..c007ef90 --- /dev/null +++ b/mplot/VisualFaceAsm.h @@ -0,0 +1,36 @@ +// See also VisualFaceAsm.c + +// These external pointers are set up by the inline assembly above +#ifndef _MSC_VER +extern const char __start_verabd_ttf[]; +extern const char __stop_verabd_ttf[]; +extern const char __start_verabi_ttf[]; +extern const char __stop_verabi_ttf[]; +extern const char __start_verait_ttf[]; +extern const char __stop_verait_ttf[]; +extern const char __start_veramobd_ttf[]; +extern const char __stop_veramobd_ttf[]; +extern const char __start_veramobi_ttf[]; +extern const char __stop_veramobi_ttf[]; +extern const char __start_veramoit_ttf[]; +extern const char __stop_veramoit_ttf[]; +extern const char __start_veramono_ttf[]; +extern const char __stop_veramono_ttf[]; +extern const char __start_verasebd_ttf[]; +extern const char __stop_verasebd_ttf[]; +extern const char __start_verase_ttf[]; +extern const char __stop_verase_ttf[]; +extern const char __start_vera_ttf[]; +extern const char __stop_vera_ttf[]; + +extern const char __start_dvsans_ttf[]; +extern const char __stop_dvsans_ttf[]; +extern const char __start_dvsansit_ttf[]; +extern const char __stop_dvsansit_ttf[]; +extern const char __start_dvsansbd_ttf[]; +extern const char __stop_dvsansbd_ttf[]; +extern const char __start_dvsansbi_ttf[]; +extern const char __stop_dvsansbi_ttf[]; +#endif + +namespace meaningless { int function(); } From 15313c5f1c1dfd359e51d99bbab99ea913c084bf Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 6 Mar 2026 15:56:06 +0000 Subject: [PATCH 021/106] Helloworld now runssgit add -u --- mplot/CoordArrows.h | 8 ++++---- mplot/Visual.h | 6 ------ mplot/VisualOwnable.h | 9 ++++----- mplot/VisualResources.h | 1 + mplot/VisualTextModel.h | 30 ++++++------------------------ 5 files changed, 15 insertions(+), 39 deletions(-) diff --git a/mplot/CoordArrows.h b/mplot/CoordArrows.h index 0eb6322e..c2bd2420 100644 --- a/mplot/CoordArrows.h +++ b/mplot/CoordArrows.h @@ -146,7 +146,7 @@ export namespace mplot std::unique_ptr> makeVisualTextModel(const mplot::TextFeatures& tfeatures) { auto tmup = std::make_unique> (tfeatures); - //this->bindmodel (tmup); + tmup->set_parent (this->parentVis); return tmup; } @@ -317,10 +317,10 @@ export namespace mplot GladGLContext* glfn = nullptr; - protected: + // The mplot::Visual in which this model exists. + uint32_t parentVis = std::numeric_limits::max(); - // The mplot::VisualBase in which this model exists. - //mplot::VisualBase* parentVis = nullptr; + protected: //! The current indices index uint32_t idx = 0u; diff --git a/mplot/Visual.h b/mplot/Visual.h index 6037397b..baa5dd80 100644 --- a/mplot/Visual.h +++ b/mplot/Visual.h @@ -71,12 +71,6 @@ export namespace mplot this->init_resources(); this->init_gl(); // could this come before init_resources? NO, because init_gl has // VisualTextModel stuff that requires init_resources. Could maybe split init_gl - -#if 0 // To go! - // Special tasks: re-bind coordArrows and title text - this->bindextra (this->coordArrows); - this->bindextra (this->textModel); -#endif } //! Deconstructor destroys GLFW/Qt window and deregisters access to VisualResources diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index 3d805b46..1df03601 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -558,7 +558,7 @@ export namespace mplot this->setContext(); if (this->shaders.tprog == 0) { throw std::runtime_error ("No text shader prog."); } auto tmup = std::make_unique> (tfeatures); - + tmup->set_parent (this->visual_id); if (tfeatures.centre_horz == true) { mplot::TextGeometry tg = tmup->getTextGeometry(_text); sm::vec centred_locn = _toffset; @@ -584,7 +584,7 @@ export namespace mplot this->setContext(); if (this->shaders.tprog == 0) { throw std::runtime_error ("No text shader prog."); } auto tmup = std::make_unique> (tfeatures); - + tmup->set_parent (this->visual_id); if (tfeatures.centre_horz == true) { mplot::TextGeometry tg = tmup->getTextGeometry(_text); sm::vec centred_locn = _toffset; @@ -667,10 +667,9 @@ export namespace mplot this->coordArrows = std::make_unique>(); this->coordArrows->glfn = this->glfn; this->coordArrows->gprog = this->shaders.gprog; + this->coordArrows->parentVis = this->visual_id; // And NOW we can proceed to init (lengths, thickness, em size for labels): this->coordArrows->init (sm::vec<>{0.1f, 0.1f, 0.1f}, 1.0f, 0.01f); - - // Prolly don't need the finalize scheme with CoordArrows this->coordArrows->finalize(); // VisualModel::finalize releases context (normally this is the right thing)... this->setContext(); // ...but we've got more work to do, so re-acquire context (if we're managing it) @@ -679,7 +678,7 @@ export namespace mplot // Set up the title, which may or may not be rendered mplot::TextFeatures title_tf(0.035f, 64); this->textModel = std::make_unique> (title_tf); - + this->textModel->set_parent (this->visual_id); this->textModel->setSceneTranslation ({0.0f, 0.0f, 0.0f}); this->textModel->setupText (this->title); diff --git a/mplot/VisualResources.h b/mplot/VisualResources.h index 398ab044..f8ba5af5 100644 --- a/mplot/VisualResources.h +++ b/mplot/VisualResources.h @@ -186,6 +186,7 @@ export namespace mplot this->visual_keyed_shaderprogs[visual_id] = {}; // initialized empty with 0s this->visual_keyed_windows[visual_id] = win; this->visual_keyed_instanced_needs_update[visual_id] = false; + std::cout << "Registered Visual ID " << visual_id << std::endl; return visual_id; } diff --git a/mplot/VisualTextModel.h b/mplot/VisualTextModel.h index 4fab489c..4aaa5107 100644 --- a/mplot/VisualTextModel.h +++ b/mplot/VisualTextModel.h @@ -201,6 +201,8 @@ export namespace mplot { constexpr bool debug_textquads = false; + std::cout << "Accessing VisualResources, parentVis is " << this->parentVis << std::endl; + if (this->face == nullptr) { GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->parentVis); this->face = VisualResources::i().getVisualFace (this->tfeatures, this->parentVis, _glfn); @@ -479,34 +481,14 @@ export namespace mplot //! Parent Visual. The mplot::Visual ID to which I belong. max means unset. uint32_t parentVis = std::numeric_limits::max(); -#if 0 - /*! - * Callbacks are analogous to those in VisualModel - */ - std::function*)> get_shaderprogs; - //! Get the graphics shader prog id - std::function*)> get_gprog; - //! Get the text shader prog id - std::function*)> get_tprog; - - //! Set OpenGL context. Should call parentVis->setContext(). - std::function*)> setContext; - //! Release OpenGL context. Should call parentVis->releaseContext(). - std::function*)> releaseContext; - - //! SSBOs are unused in VisualTextModels, but these functions have to be present - std::function*, const unsigned int)> init_instance_data; - std::function&)> insert_instance_data; - std::function&, const float, const float)> insert_instparam_data; - std::function*)> instanced_needs_update; - //! Setter for the parent pointer, parentVis - void set_parent (mplot::VisualBase* _vis) + void set_parent (const uint32_t _vis) { - //if (this->parentVis != nullptr) { throw std::runtime_error ("VisualTextModel: Set the parent pointer once only!"); } + if (this->parentVis != std::numeric_limits::max()) { + throw std::runtime_error ("VisualTextModel: Set the parent pointer once only!"); + } this->parentVis = _vis; } -#endif protected: // The text features for this VisualTextModel From 9312e7a422a06395ce019e73fa842cfb79cb34d1 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 6 Mar 2026 16:57:08 +0000 Subject: [PATCH 022/106] Trying to make helloworld and rod work in clang-20 and gcc-15. Not there yet --- .gitmodules | 3 + CMakeLists.txt | 4 +- examples/CMakeLists.txt | 22 +- examples/helloworld.cpp | 4 +- examples/rod.cpp | 59 +- json | 1 + mplot/CoordArrows.h | 11 +- mplot/TextFeatures.h | 2 +- mplot/Visual.h | 12 +- mplot/VisualCommon.h | 2 +- mplot/VisualDefaultShaders.h | 2 +- mplot/VisualGlfw.h | 5 +- mplot/VisualModel.h | 23 +- mplot/VisualOwnable.h | 38 +- mplot/VisualResources.h | 2 +- mplot/VisualTextModel.h | 15 +- mplot/colour.h | 1395 +++++++++++++++++----------------- mplot/core.ixx | 2 - mplot/gl/version.h | 52 +- 19 files changed, 805 insertions(+), 849 deletions(-) create mode 160000 json delete mode 100644 mplot/core.ixx diff --git a/.gitmodules b/.gitmodules index 5c7b9364..9c133669 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "maths"] path = maths url = https://github.com/sebsjames/maths +[submodule "json"] + path = json + url = https://github.com/nlohmann/json diff --git a/CMakeLists.txt b/CMakeLists.txt index eb1ddd7a..9a9cd024 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,7 +155,9 @@ else() endif() # Use packaged nlohmann json -find_package(nlohmann_json REQUIRED) +# find_package(nlohmann_json REQUIRED) +# Now nlohmann is submoduled to get an up-to-date version (for C++ modules) +include_directories("${PROJECT_SOURCE_DIR}/json/include") # If Qt5 is present, then some optional Qt examples will be compiled find_package(Qt5 QUIET COMPONENTS Gui Core Widgets) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index d71b59d4..bc88b2ab 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -37,14 +37,16 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h ${PROJECT_SOURCE_DIR}/mplot/win_t.h - ${PROJECT_SOURCE_DIR}/mplot/core.ixx + ${PROJECT_SOURCE_DIR}/mplot/colour.h + ${PROJECT_SOURCE_DIR}/mplot/gl/version.h PROPERTIES LANGUAGE CXX ) add_executable(helloworld helloworld.cpp) target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES - ${PROJECT_SOURCE_DIR}/mplot/core.ixx + ${PROJECT_SOURCE_DIR}/mplot/gl/version.h + ${PROJECT_SOURCE_DIR}/mplot/colour.h ${PROJECT_SOURCE_DIR}/mplot/win_t.h ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h @@ -72,6 +74,20 @@ target_link_libraries(helloworld OpenGL::GL glfw Freetype::Freetype glad mplot_f add_executable(rod rod.cpp) target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES + ${PROJECT_SOURCE_DIR}/mplot/gl/version.h + ${PROJECT_SOURCE_DIR}/mplot/colour.h + ${PROJECT_SOURCE_DIR}/mplot/win_t.h + ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h + ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h + ${PROJECT_SOURCE_DIR}/mplot/Visual.h + ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h + ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h + ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h + ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h + ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h + ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h ${PROJECT_SOURCE_DIR}/maths/sm/flags ${PROJECT_SOURCE_DIR}/maths/sm/algo ${PROJECT_SOURCE_DIR}/maths/sm/range @@ -82,7 +98,7 @@ target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/maths/sm/geometry ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra ${PROJECT_SOURCE_DIR}/maths/sm/vvec) -target_link_libraries(rod OpenGL::GL glfw Freetype::Freetype) +target_link_libraries(rod OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) # mplot::Grid is runtime-configured add_executable(grid_simple grid_simple.cpp) diff --git a/examples/helloworld.cpp b/examples/helloworld.cpp index d3ed7995..55244ca5 100644 --- a/examples/helloworld.cpp +++ b/examples/helloworld.cpp @@ -1,5 +1,5 @@ -#include -import mplot.core; +import mplot.visual; +import mplot.gl.version; int main() { diff --git a/examples/rod.cpp b/examples/rod.cpp index 5ccdb8d5..28d7cd31 100644 --- a/examples/rod.cpp +++ b/examples/rod.cpp @@ -2,16 +2,13 @@ * Visualize a Rod */ #include -#include -#include -#include -#include -#include -#include -#include // import mplot.core; +import mplot.visual; +import mplot.gl.version; -#include // import mplot.gridvisual; +#include + +//#include // import mplot.gridvisual; import sm.vec; @@ -28,32 +25,26 @@ int main() // Switch on a mix of diffuse/ambient lighting v.lightingEffects(true); - try { - constexpr sm::vec colour1 = { 1.0, 0.0, 0.0 }; - constexpr sm::vec colour2 = { 0.0, 0.9, 0.4 }; - - sm::vec offset = { 0.0, 0.0, 0.0 }; - sm::vec start = { 0, 0, 0 }; - sm::vec end = { 0.25, 0, 0 }; - std::unique_ptr> rvm = std::make_unique> (offset, start, end, 0.1f, colour1, colour1); - v.bindmodel (rvm); - rvm->finalize(); - v.addVisualModel (rvm); - - sm::vec start2 = { -0.1, 0.2, 0.6 }; - sm::vec end2 = { 0.2, 0.4, 0.6 }; - // You can reuse the unique_ptr rvm, once you've transferred ownership with v.addVisualModel (rvm) - rvm = std::make_unique>(offset, start2, end2, 0.05f, colour2); - v.bindmodel (rvm); - rvm->finalize(); - v.addVisualModel (rvm); - - v.keepOpen(); - - } catch (const std::exception& e) { - std::cerr << "Caught exception: " << e.what() << std::endl; - rtn = -1; - } + constexpr sm::vec colour1 = { 1.0, 0.0, 0.0 }; + constexpr sm::vec colour2 = { 0.0, 0.9, 0.4 }; + + sm::vec offset = { 0.0, 0.0, 0.0 }; + sm::vec start = { 0, 0, 0 }; + sm::vec end = { 0.25, 0, 0 }; + std::unique_ptr> rvm = std::make_unique> (offset, start, end, 0.1f, colour1, colour1); + v.bindmodel (rvm); + rvm->finalize(); + v.addVisualModel (rvm); + + sm::vec start2 = { -0.1, 0.2, 0.6 }; + sm::vec end2 = { 0.2, 0.4, 0.6 }; + // You can reuse the unique_ptr rvm, once you've transferred ownership with v.addVisualModel (rvm) + rvm = std::make_unique>(offset, start2, end2, 0.05f, colour2); + v.bindmodel (rvm); + rvm->finalize(); + v.addVisualModel (rvm); + + v.keepOpen(); return rtn; } diff --git a/json b/json new file mode 160000 index 00000000..f534f4f7 --- /dev/null +++ b/json @@ -0,0 +1 @@ +Subproject commit f534f4f75e12893716ea688679aeb768bff426c4 diff --git a/mplot/CoordArrows.h b/mplot/CoordArrows.h index c2bd2420..423de798 100644 --- a/mplot/CoordArrows.h +++ b/mplot/CoordArrows.h @@ -21,15 +21,16 @@ module; #include -#include #include -#include -export module mplot.core:coordarrows; +export module mplot.coordarrows; import mplot.visualtextmodel; import mplot.textfeatures; import mplot.visualfont; +import mplot.visualcommon; +import mplot.colour; +import mplot.gl.version; import sm.vec; import sm.mat; import sm.flags; @@ -264,10 +265,6 @@ export namespace mplot if (loc_s != -1) { this->glfn->UniformMatrix4fv (loc_s, 1, GL_FALSE, idmat.arr.data()); } // Draw the triangles - //GLint loc_is = this->glfn->GetUniformLocation (gprog, static_cast("instance_start")); - //GLint loc_ic = this->glfn->GetUniformLocation (gprog, static_cast("instance_count")); - //if (loc_is != -1) { this->glfn->Uniform1i (loc_is, -1); } - //if (loc_ic != -1) { this->glfn->Uniform1i (loc_ic, -1); } this->glfn->DrawElements (GL_TRIANGLES, static_cast(this->indices.size()), GL_UNSIGNED_INT, 0); // Unbind the VAO diff --git a/mplot/TextFeatures.h b/mplot/TextFeatures.h index f358675e..5a5b0595 100644 --- a/mplot/TextFeatures.h +++ b/mplot/TextFeatures.h @@ -1,11 +1,11 @@ module; #include -#include export module mplot.textfeatures; import mplot.visualfont; +import mplot.colour; export namespace mplot { diff --git a/mplot/Visual.h b/mplot/Visual.h index baa5dd80..18583a85 100644 --- a/mplot/Visual.h +++ b/mplot/Visual.h @@ -24,15 +24,17 @@ module; #include #include +#include -#include - -export module mplot.core:visual; +export module mplot.visual; export import mplot.win_t; import mplot.visualresources; -export import :visualglfw; -export import :visualownable; + +export import mplot.visualglfw; +import mplot.visualownable; + +import mplot.gl.version; export namespace mplot { diff --git a/mplot/VisualCommon.h b/mplot/VisualCommon.h index 74a74f1f..fad501fc 100644 --- a/mplot/VisualCommon.h +++ b/mplot/VisualCommon.h @@ -11,7 +11,6 @@ module; #include #include #include -#include export module mplot.visualcommon; @@ -19,6 +18,7 @@ import sm.vec; import sm.range; import sm.vvec; import sm.mat; +import mplot.colour; export namespace mplot { diff --git a/mplot/VisualDefaultShaders.h b/mplot/VisualDefaultShaders.h index 5d2fff3d..b6017d66 100644 --- a/mplot/VisualDefaultShaders.h +++ b/mplot/VisualDefaultShaders.h @@ -3,7 +3,7 @@ #pragma once -#include +import mplot.gl.version; namespace mplot { diff --git a/mplot/VisualGlfw.h b/mplot/VisualGlfw.h index 2933c7b4..550d85c0 100644 --- a/mplot/VisualGlfw.h +++ b/mplot/VisualGlfw.h @@ -15,9 +15,10 @@ module; #include #include -#include -export module mplot.core:visualglfw; +export module mplot.visualglfw; + +import mplot.gl.version; export namespace mplot { diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index c8d02e84..f91f3b4c 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -34,7 +34,6 @@ #include #include -#include #include #include @@ -53,10 +52,9 @@ import sm.flags; import mplot.visualcommon; import mplot.visualresources; import mplot.visualtextmodel; +import mplot.colour; +import mplot.gl.version; -//import mplot.core;// Can I avoid use of this in VisualModelBase? - -#include #include #include @@ -68,16 +66,6 @@ namespace mplot uint8_t bytes[sizeof(float)]; }; - //! Forward declaration of a Visual class - // Right now, models need to know about VisualBase to: - // get shader progs - // set/get context - // - // Could I have a singleton that can do the work and is a separate class so taht VisualModel no - // longer needs to know about VisualBase? Visual registers its identity and the shader programs - // and the singleton could set context based on an id that the VisualModel contains? - //template class VisualBase; - /*! * An OpenGL model class * @@ -1138,13 +1126,6 @@ namespace mplot //! If drawing with instancing, how many params will be used (these will be cycled through //! per-instance and there may be fewer than instance_count parameters) unsigned int instparam_count = 0; -#if 0 - //! Init the SSBOs for instanced rendering - std::function*, const unsigned int)> init_instance_data; - std::function&)> insert_instance_data; - std::function&, const float, const float)> insert_instparam_data; - std::function*)> instanced_needs_update; -#endif //! Set the scaling matrix for all instances void set_instance_scale (const float scl) diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index 1df03601..bdbf6b9d 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -30,7 +30,6 @@ module; #include #include #include -#include #include #include @@ -49,7 +48,7 @@ module; #include -export module mplot.core:visualownable; +export module mplot.visualownable; import mplot.win_t; import mplot.visualcommon; @@ -57,7 +56,8 @@ import mplot.visualresources; import mplot.visualtextmodel; import mplot.textgeometry; import mplot.textfeatures; -import :coordarrows; +import mplot.coordarrows; +import mplot.gl.version; import sm.vec; @@ -216,7 +216,8 @@ export namespace mplot // Explicitly deconstruct coordArrows, textModel and texts here this->coordArrows.reset (nullptr); this->textModel.reset (nullptr); - for (auto& t : this->texts) { t.reset (nullptr); } + for (uint32_t i = 0; i < this->texts.size(); ++i) { this->texts[i].reset (nullptr); } + //for (auto& t : this->texts) { t.reset (nullptr); } if (this->shaders.gprog) { this->glfn->DeleteProgram (this->shaders.gprog); @@ -598,29 +599,7 @@ export namespace mplot this->releaseContext(); return tm->getTextGeometry(); } -#if 0 // code to use VisualResources directly - static unsigned int init_instance_data (mplot::VisualOwnable* _v, const unsigned int n_to_reserve) - { - unsigned int reservation = mplot::VisualResources::i().init_instance_ssbo (_v->glfn, n_to_reserve); - return reservation; - } - - static void insert_instance_data (const unsigned int instance_idx, const sm::vec& coord) - { - mplot::VisualResources::i().insert_instance_data (instance_idx, coord); - } - - static void insert_instparam_data (const unsigned int instance_idx, - const std::array& colour, const float& alpha, const float& scale) - { - mplot::VisualResources::i().insert_instparam_data (instance_idx, colour, alpha, scale); - } - static void copy_instance_data_to_gpu() - { - mplot::VisualResources::i().copy_instance_ssbo_to_gpu(); - } -#endif protected: // Initialize OpenGL shaders, set some flags (Alpha, Anti-aliasing), read in any external // state from json, and set up the coordinate arrows and any VisualTextModels that will be @@ -700,13 +679,6 @@ export namespace mplot std::vector proj2d_shader_progs; //! Stores the info required to load the text shader std::vector text_shader_progs; -#if 0 // To go - // These static functions will be set as callbacks in each VisualModel object. - static mplot::visgl::visual_shaderprogs get_shaderprogs (mplot::VisualOwnable* _v) { return _v->shaders; }; - static GLuint get_gprog (mplot::VisualOwnable* _v) { return _v->shaders.gprog; }; - static GLuint get_tprog (mplot::VisualOwnable* _v) { return _v->shaders.tprog; }; - static void instanced_needs_update (mplot::VisualOwnable* _v) { _v->instancedNeedsUpdate (true); } //next -#endif //! The colour of ambient and diffuse light sources sm::vec light_colour = { 1.0f, 1.0f, 1.0f }; diff --git a/mplot/VisualResources.h b/mplot/VisualResources.h index f8ba5af5..a5ea941b 100644 --- a/mplot/VisualResources.h +++ b/mplot/VisualResources.h @@ -28,7 +28,6 @@ module; #include #include #include -#include #include #include @@ -39,6 +38,7 @@ import mplot.visualface; import mplot.visualfont; import mplot.textfeatures; import mplot.win_t; +import mplot.gl.version; import sm.vec; diff --git a/mplot/VisualTextModel.h b/mplot/VisualTextModel.h index 4aaa5107..66e7a461 100644 --- a/mplot/VisualTextModel.h +++ b/mplot/VisualTextModel.h @@ -27,10 +27,8 @@ module; #include -#include #include #include -#include export module mplot.visualtextmodel; @@ -39,6 +37,8 @@ import mplot.visualcommon; export import mplot.textgeometry; export import mplot.textfeatures; import mplot.visualface; +import mplot.colour; +import mplot.gl.version; import sm.quaternion; import sm.mat; @@ -46,9 +46,6 @@ import sm.vec; export namespace mplot { - //! Forward declaration of a VisualBase class - //template class VisualBase; - /*! * This is the base class for VisualTextModel containing common code, but no GL function calls. */ @@ -132,7 +129,8 @@ export namespace mplot // First convert string from ASCII/UTF-8 into Unicode. std::basic_string utxt = mplot::unicode::fromUtf8(_txt); - for (std::basic_string::const_iterator c = utxt.begin(); c != utxt.end(); c++) { + // on g++ 15 there's an issue with operator!= when used in a module + for (std::basic_string::const_iterator c = utxt.cbegin(); c != utxt.cend(); c++) { mplot::visgl::CharInfo ci = this->face->glchars[*c]; float drop = (ci.size.y() - ci.bearing.y()) * this->fontscale; geom.max_drop = (drop > geom.max_drop) ? drop : geom.max_drop; @@ -165,10 +163,6 @@ export namespace mplot return geom; } - //! For some reason, I can't place these setupText functions in the base class. Compiler - //! gets confused wtih std::string aka std::__cxx11::basic_string and - //! std::__cxx11::basic_string - //!{ //! Set up a new text at a given position, with the given colour. void setupText (const std::string& _txt, const sm::vec _offset, std::array _clr = {0,0,0}) @@ -194,7 +188,6 @@ export namespace mplot // Convert std::string _txt to std::basic_string text and call the other setupText this->setupText (mplot::unicode::fromUtf8 (_txt)); } - //!} //! With the given text and font size information, create the quads for the text. void setupText (const std::basic_string& _txt) diff --git a/mplot/colour.h b/mplot/colour.h index f806f7e0..a7aff5fd 100644 --- a/mplot/colour.h +++ b/mplot/colour.h @@ -6,705 +6,704 @@ * Author: Seb James * Date: Nov 2020 */ - -#pragma once - +module; #include +export module mplot.colour; -namespace mplot::colour +export namespace mplot::colour { - static constexpr std::array indian_red = {0.6901960784f,0.0901960784f,0.1215686275f}; - static constexpr std::array crimson = {0.862745098f,0.0784313725f,0.2352941176f}; - static constexpr std::array lightpink = {1.0f,0.7137254902f,0.7568627451f}; - static constexpr std::array lightpink1 = {1.0f,0.6823529412f,0.7254901961f}; - static constexpr std::array lightpink2 = {0.9333333333f,0.6352941176f,0.6784313725f}; - static constexpr std::array lightpink3 = {0.8039215686f,0.5490196078f,0.5843137255f}; - static constexpr std::array lightpink4 = {0.5450980392f,0.3725490196f,0.3960784314f}; - static constexpr std::array pink = {1.0f,0.7529411765f,0.7960784314f}; - static constexpr std::array pink1 = {1.0f,0.7098039216f,0.7725490196f}; - static constexpr std::array pink2 = {0.9333333333f,0.662745098f,0.7215686275f}; - static constexpr std::array pink3 = {0.8039215686f,0.568627451f,0.6196078431f}; - static constexpr std::array pink4 = {0.5450980392f,0.3882352941f,0.4235294118f}; - static constexpr std::array palevioletred = {0.8588235294f,0.4392156863f,0.5764705882f}; - static constexpr std::array palevioletred1 = {1.0f,0.5098039216f,0.6705882353f}; - static constexpr std::array palevioletred2 = {0.9333333333f,0.4745098039f,0.6235294118f}; - static constexpr std::array palevioletred3 = {0.8039215686f,0.4078431373f,0.537254902f}; - static constexpr std::array palevioletred4 = {0.5450980392f,0.2784313725f,0.3647058824f}; - static constexpr std::array lavenderblush = {1.0f,0.9411764706f,0.9607843137f}; - static constexpr std::array lavenderblush1 = lavenderblush; - static constexpr std::array lavenderblush2 = {0.9333333333f,0.8784313725f,0.8980392157f}; - static constexpr std::array lavenderblush3 = {0.8039215686f,0.7568627451f,0.7725490196f}; - static constexpr std::array lavenderblush4 = {0.5450980392f,0.5137254902f,0.5254901961f}; - static constexpr std::array violetred1 = {1.0f,0.2431372549f,0.5882352941f}; - static constexpr std::array violetred2 = {0.9333333333f,0.2274509804f,0.5490196078f}; - static constexpr std::array violetred3 = {0.8039215686f,0.1960784314f,0.4705882353f}; - static constexpr std::array violetred4 = {0.5450980392f,0.1333333333f,0.3215686275f}; - static constexpr std::array hotpink = {1.0f,0.4117647059f,0.7058823529f}; - static constexpr std::array hotpink1 = {1.0f,0.431372549f,0.7058823529f}; - static constexpr std::array hotpink2 = {0.9333333333f,0.4156862745f,0.6549019608f}; - static constexpr std::array hotpink3 = {0.8039215686f,0.3764705882f,0.5647058824f}; - static constexpr std::array hotpink4 = {0.5450980392f,0.2274509804f,0.3843137255f}; - static constexpr std::array raspberry = {0.5294117647f,0.1490196078f,0.3411764706f}; - static constexpr std::array deeppink = {1.0f,0.0784313725f,0.5764705882f}; - static constexpr std::array deeppink1 = {1.0f,0.0784313725f,0.5764705882f}; - static constexpr std::array deeppink2 = {0.9333333333f,0.0705882353f,0.537254902f}; - static constexpr std::array deeppink3 = {0.8039215686f,0.062745098f,0.462745098f}; - static constexpr std::array deeppink4 = {0.5450980392f,0.0392156863f,0.3137254902f}; - static constexpr std::array maroon1 = {1.0f,0.2039215686f,0.7019607843f}; - static constexpr std::array maroon2 = {0.9333333333f,0.1882352941f,0.6549019608f}; - static constexpr std::array maroon3 = {0.8039215686f,0.1607843137f,0.5647058824f}; - static constexpr std::array maroon4 = {0.5450980392f,0.1098039216f,0.3843137255f}; - static constexpr std::array mediumvioletred = {0.7803921569f,0.0823529412f,0.5215686275f}; - static constexpr std::array violetred = {0.8156862745f,0.1254901961f,0.5647058824f}; - static constexpr std::array orchid = {0.8549019608f,0.4392156863f,0.8392156863f}; - static constexpr std::array orchid1 = {1.0f,0.5137254902f,0.9803921569f}; - static constexpr std::array orchid2 = {0.9333333333f,0.4784313725f,0.9137254902f}; - static constexpr std::array orchid3 = {0.8039215686f,0.4117647059f,0.7882352941f}; - static constexpr std::array orchid4 = {0.5450980392f,0.2784313725f,0.537254902f}; - static constexpr std::array thistle = {0.8470588235f,0.7490196078f,0.8470588235f}; - static constexpr std::array thistle1 = {1.0f,0.8823529412f,1.0f}; - static constexpr std::array thistle2 = {0.9333333333f,0.8235294118f,0.9333333333f}; - static constexpr std::array thistle3 = {0.8039215686f,0.7098039216f,0.8039215686f}; - static constexpr std::array thistle4 = {0.5450980392f,0.4823529412f,0.5450980392f}; - static constexpr std::array plum1 = {1.0f,0.7333333333f,1.0f}; - static constexpr std::array plum2 = {0.9333333333f,0.6823529412f,0.9333333333f}; - static constexpr std::array plum3 = {0.8039215686f,0.5882352941f,0.8039215686f}; - static constexpr std::array plum4 = {0.5450980392f,0.4f,0.5450980392f}; - static constexpr std::array plum = {0.8666666667f,0.6274509804f,0.8666666667f}; - static constexpr std::array violet = {0.9333333333f,0.5098039216f,0.9333333333f}; - static constexpr std::array magenta = {1.0f,0.0f,1.0f}; - static constexpr std::array fuchsia = magenta; - static constexpr std::array magenta2 = {0.9333333333f,0.0f,0.9333333333f}; - static constexpr std::array magenta3 = {0.8039215686f,0.0f,0.8039215686f}; - static constexpr std::array magenta4 = {0.5450980392f,0.0f,0.5450980392f}; - static constexpr std::array darkmagenta = magenta4; - static constexpr std::array purple = {0.5019607843f,0.0f,0.5019607843f}; - static constexpr std::array mediumorchid = {0.7294117647f,0.3333333333f,0.8274509804f}; - static constexpr std::array mediumorchid1 = {0.8784313725f,0.4f,1.0f}; - static constexpr std::array mediumorchid2 = {0.8196078431f,0.3725490196f,0.9333333333f}; - static constexpr std::array mediumorchid3 = {0.7058823529f,0.3215686275f,0.8039215686f}; - static constexpr std::array mediumorchid4 = {0.4784313725f,0.2156862745f,0.5450980392f}; - static constexpr std::array darkviolet = {0.5803921569f,0.0f,0.8274509804f}; - static constexpr std::array darkorchid = {0.6f,0.1960784314f,0.8f}; - static constexpr std::array darkorchid1 = {0.7490196078f,0.2431372549f,1.0f}; - static constexpr std::array darkorchid2 = {0.6980392157f,0.2274509804f,0.9333333333f}; - static constexpr std::array darkorchid3 = {0.6039215686f,0.1960784314f,0.8039215686f}; - static constexpr std::array darkorchid4 = {0.4078431373f,0.1333333333f,0.5450980392f}; - static constexpr std::array indigo = {0.2941176471f,0.0f,0.5098039216f}; - static constexpr std::array blueviolet = {0.5411764706f,0.168627451f,0.8862745098f}; - static constexpr std::array purple1 = {0.6078431373f,0.1882352941f,1.0f}; - static constexpr std::array purple2 = {0.568627451f,0.1725490196f,0.9333333333f}; - static constexpr std::array purple3 = {0.4901960784f,0.1490196078f,0.8039215686f}; - static constexpr std::array purple4 = {0.3333333333f,0.1019607843f,0.5450980392f}; - static constexpr std::array mediumpurple = {0.5764705882f,0.4392156863f,0.8588235294f}; - static constexpr std::array mediumpurple1 = {0.6705882353f,0.5098039216f,1.0f}; - static constexpr std::array mediumpurple2 = {0.6235294118f,0.4745098039f,0.9333333333f}; - static constexpr std::array mediumpurple3 = {0.537254902f,0.4078431373f,0.8039215686f}; - static constexpr std::array mediumpurple4 = {0.3647058824f,0.2784313725f,0.5450980392f}; - static constexpr std::array darkslateblue = {0.2823529412f,0.2392156863f,0.5450980392f}; - static constexpr std::array lightslateblue = {0.5176470588f,0.4392156863f,1.0f}; - static constexpr std::array mediumslateblue = {0.4823529412f,0.4078431373f,0.9333333333f}; - static constexpr std::array slateblue = {0.4156862745f,0.3529411765f,0.8039215686f}; - static constexpr std::array slateblue1 = {0.5137254902f,0.4352941176f,1.0f}; - static constexpr std::array slateblue2 = {0.4784313725f,0.4039215686f,0.9333333333f}; - static constexpr std::array slateblue3 = {0.4117647059f,0.3490196078f,0.8039215686f}; - static constexpr std::array slateblue4 = {0.2784313725f,0.2352941176f,0.5450980392f}; - static constexpr std::array ghostwhite = {0.9725490196f,0.9725490196f,1.0f}; - static constexpr std::array lavender = {0.9019607843f,0.9019607843f,0.9803921569f}; - static constexpr std::array blue = {0.0f,0.0f,1.0f}; - static constexpr std::array blue1 = blue; - static constexpr std::array blue2 = {0.0f,0.0f,0.9333333333f}; - static constexpr std::array blue3 = {0.0f,0.0f,0.8039215686f}; - static constexpr std::array mediumblue = blue3; - static constexpr std::array blue4 = {0.0f,0.0f,0.5450980392f}; - static constexpr std::array darkblue = blue4; - static constexpr std::array navy = {0.0f,0.0f,0.5019607843f}; - static constexpr std::array midnightblue = {0.0980392157f,0.0980392157f,0.4392156863f}; - static constexpr std::array cobalt = {0.2392156863f,0.3490196078f,0.6705882353f}; - static constexpr std::array royalblue = {0.2549019608f,0.4117647059f,0.8823529412f}; - static constexpr std::array royalblue1 = {0.2823529412f,0.462745098f,1.0f}; - static constexpr std::array royalblue2 = {0.262745098f,0.431372549f,0.9333333333f}; - static constexpr std::array royalblue3 = {0.2274509804f,0.3725490196f,0.8039215686f}; - static constexpr std::array royalblue4 = {0.1529411765f,0.2509803922f,0.5450980392f}; - static constexpr std::array cornflowerblue = {0.3921568627f,0.5843137255f,0.9294117647f}; - static constexpr std::array lightsteelblue = {0.6901960784f,0.768627451f,0.8705882353f}; - static constexpr std::array lightsteelblue1 = {0.7921568627f,0.8823529412f,1.0f}; - static constexpr std::array lightsteelblue2 = {0.737254902f,0.8235294118f,0.9333333333f}; - static constexpr std::array lightsteelblue3 = {0.6352941176f,0.7098039216f,0.8039215686f}; - static constexpr std::array lightsteelblue4 = {0.431372549f,0.4823529412f,0.5450980392f}; - static constexpr std::array lightslategray = {0.4666666667f,0.5333333333f,0.6f}; - static constexpr std::array slategray = {0.4392156863f,0.5019607843f,0.5647058824f}; - static constexpr std::array slategray1 = {0.7764705882f,0.8862745098f,1.0f}; - static constexpr std::array slategray2 = {0.7254901961f,0.8274509804f,0.9333333333f}; - static constexpr std::array slategray3 = {0.6235294118f,0.7137254902f,0.8039215686f}; - static constexpr std::array slategray4 = {0.4235294118f,0.4823529412f,0.5450980392f}; - static constexpr std::array dodgerblue = {0.1176470588f,0.5647058824f,1.0f}; - static constexpr std::array dodgerblue1 = dodgerblue; - static constexpr std::array dodgerblue2 = {0.1098039216f,0.5254901961f,0.9333333333f}; - static constexpr std::array dodgerblue3 = {0.0941176471f,0.4549019608f,0.8039215686f}; - static constexpr std::array dodgerblue4 = {0.062745098f,0.3058823529f,0.5450980392f}; - static constexpr std::array aliceblue = {0.9411764706f,0.9725490196f,1.0f}; - static constexpr std::array steelblue = {0.2745098039f,0.5098039216f,0.7058823529f}; - static constexpr std::array steelblue1 = {0.3882352941f,0.7215686275f,1.0f}; - static constexpr std::array steelblue2 = {0.3607843137f,0.6745098039f,0.9333333333f}; - static constexpr std::array steelblue3 = {0.3098039216f,0.5803921569f,0.8039215686f}; - static constexpr std::array steelblue4 = {0.2117647059f,0.3921568627f,0.5450980392f}; - static constexpr std::array lightskyblue = {0.5294117647f,0.8078431373f,0.9803921569f}; - static constexpr std::array lightskyblue1 = {0.6901960784f,0.8862745098f,1.0f}; - static constexpr std::array lightskyblue2 = {0.6431372549f,0.8274509804f,0.9333333333f}; - static constexpr std::array lightskyblue3 = {0.5529411765f,0.7137254902f,0.8039215686f}; - static constexpr std::array lightskyblue4 = {0.3764705882f,0.4823529412f,0.5450980392f}; - static constexpr std::array skyblue = {0.5294117647f,0.8078431373f,0.9215686275f}; - static constexpr std::array skyblue1 = {0.5294117647f,0.8078431373f,1.0f}; - static constexpr std::array skyblue2 = {0.4941176471f,0.7529411765f,0.9333333333f}; - static constexpr std::array skyblue3 = {0.4235294118f,0.6509803922f,0.8039215686f}; - static constexpr std::array skyblue4 = {0.2901960784f,0.4392156863f,0.5450980392f}; - static constexpr std::array deepskyblue = {0.0f,0.7490196078f,1.0f}; - static constexpr std::array deepskyblue1 = deepskyblue; - static constexpr std::array deepskyblue2 = {0.0f,0.6980392157f,0.9333333333f}; - static constexpr std::array deepskyblue3 = {0.0f,0.6039215686f,0.8039215686f}; - static constexpr std::array deepskyblue4 = {0.0f,0.4078431373f,0.5450980392f}; - static constexpr std::array peacock = {0.2f,0.631372549f,0.7882352941f}; - static constexpr std::array lightblue = {0.6784313725f,0.8470588235f,0.9019607843f}; - static constexpr std::array lightblue1 = {0.7490196078f,0.937254902f,1.0f}; - static constexpr std::array lightblue2 = {0.6980392157f,0.8745098039f,0.9333333333f}; - static constexpr std::array lightblue3 = {0.6039215686f,0.7529411765f,0.8039215686f}; - static constexpr std::array lightblue4 = {0.4078431373f,0.5137254902f,0.5450980392f}; - static constexpr std::array powderblue = {0.6901960784f,0.8784313725f,0.9019607843f}; - static constexpr std::array cadetblue1 = {0.5960784314f,0.9607843137f,1.0f}; - static constexpr std::array cadetblue2 = {0.5568627451f,0.8980392157f,0.9333333333f}; - static constexpr std::array cadetblue3 = {0.4784313725f,0.7725490196f,0.8039215686f}; - static constexpr std::array cadetblue4 = {0.3254901961f,0.5254901961f,0.5450980392f}; - static constexpr std::array turquoise1 = {0.0f,0.9607843137f,1.0f}; - static constexpr std::array turquoise2 = {0.0f,0.8980392157f,0.9333333333f}; - static constexpr std::array turquoise3 = {0.0f,0.7725490196f,0.8039215686f}; - static constexpr std::array turquoise4 = {0.0f,0.5254901961f,0.5450980392f}; - static constexpr std::array cadetblue = {0.3725490196f,0.6196078431f,0.6274509804f}; - static constexpr std::array darkturquoise = {0.0f,0.8078431373f,0.8196078431f}; - static constexpr std::array azure = {0.9411764706f,1.0f,1.0f}; - static constexpr std::array azure1 = azure; - static constexpr std::array azure2 = {0.8784313725f,0.9333333333f,0.9333333333f}; - static constexpr std::array azure3 = {0.7568627451f,0.8039215686f,0.8039215686f}; - static constexpr std::array azure4 = {0.5137254902f,0.5450980392f,0.5450980392f}; - static constexpr std::array lightcyan = {0.8784313725f,1.0f,1.0f}; - static constexpr std::array lightcyan1 = lightcyan; - static constexpr std::array lightcyan2 = {0.8196078431f,0.9333333333f,0.9333333333f}; - static constexpr std::array lightcyan3 = {0.7058823529f,0.8039215686f,0.8039215686f}; - static constexpr std::array lightcyan4 = {0.4784313725f,0.5450980392f,0.5450980392f}; - static constexpr std::array paleturquoise1 = {0.7333333333f,1.0f,1.0f}; - static constexpr std::array paleturquoise = {0.6823529412f,0.9333333333f,0.9333333333f}; - static constexpr std::array paleturquoise2 = paleturquoise; - static constexpr std::array paleturquoise3 = {0.5882352941f,0.8039215686f,0.8039215686f}; - static constexpr std::array paleturquoise4 = {0.4f,0.5450980392f,0.5450980392f}; - static constexpr std::array darkslategray = {0.1843137255f,0.3098039216f,0.3098039216f}; - static constexpr std::array darkslategray1 = {0.5921568627f,1.0f,1.0f}; - static constexpr std::array darkslategray2 = {0.5529411765f,0.9333333333f,0.9333333333f}; - static constexpr std::array darkslategray3 = {0.4745098039f,0.8039215686f,0.8039215686f}; - static constexpr std::array darkslategray4 = {0.3215686275f,0.5450980392f,0.5450980392f}; - static constexpr std::array cyan = {0.0f,1.0f,1.0f}; - static constexpr std::array cyan1 = cyan; - static constexpr std::array cyan2 = {0.0f,0.9333333333f,0.9333333333f}; - static constexpr std::array cyan3 = {0.0f,0.8039215686f,0.8039215686f}; - static constexpr std::array cyan4 = {0.0f,0.5450980392f,0.5450980392f}; - static constexpr std::array darkcyan = cyan4; - static constexpr std::array teal = {0.0f,0.5019607843f,0.5019607843f}; - static constexpr std::array mediumturquoise = {0.2823529412f,0.8196078431f,0.8f}; - static constexpr std::array lightseagreen = {0.1254901961f,0.6980392157f,0.6666666667f}; - static constexpr std::array manganeseblue = {0.0117647059f,0.6588235294f,0.6196078431f}; - static constexpr std::array turquoise = {0.2509803922f,0.8784313725f,0.8156862745f}; - static constexpr std::array coldgrey = {0.5019607843f,0.5411764706f,0.5294117647f}; - static constexpr std::array turquoiseblue = {0.0f,0.7803921569f,0.5490196078f}; - static constexpr std::array aquamarine = {0.4980392157f,1.0f,0.831372549f}; - static constexpr std::array aquamarine1 = aquamarine; - static constexpr std::array aquamarine2 = {0.462745098f,0.9333333333f,0.7764705882f}; - static constexpr std::array aquamarine3 = {0.4f,0.8039215686f,0.6666666667f}; - static constexpr std::array mediumaquamarine = aquamarine3; - static constexpr std::array aquamarine4 = {0.2705882353f,0.5450980392f,0.4549019608f}; - static constexpr std::array mediumspringgreen = {0.0f,0.9803921569f,0.6039215686f}; - static constexpr std::array mintcream = {0.9607843137f,1.0f,0.9803921569f}; - static constexpr std::array springgreen = {0.0f,1.0f,0.4980392157f}; - static constexpr std::array springgreen1 = {0.0f,0.9333333333f,0.462745098f}; - static constexpr std::array springgreen2 = {0.0f,0.8039215686f,0.4f}; - static constexpr std::array springgreen3 = {0.0f,0.5450980392f,0.2705882353f}; - static constexpr std::array mediumseagreen = {0.2352941176f,0.7019607843f,0.4431372549f}; - static constexpr std::array seagreen1 = {0.3294117647f,1.0f,0.6235294118f}; - static constexpr std::array seagreen2 = {0.3058823529f,0.9333333333f,0.5803921569f}; - static constexpr std::array seagreen3 = {0.262745098f,0.8039215686f,0.5019607843f}; - static constexpr std::array seagreen = {0.1803921569f,0.5450980392f,0.3411764706f}; - static constexpr std::array seagreen4 = seagreen; - static constexpr std::array emeraldgreen = {0.0f,0.7882352941f,0.3411764706f}; - static constexpr std::array mint = {0.7411764706f,0.9882352941f,0.7882352941f}; - static constexpr std::array cobaltgreen = {0.2392156863f,0.568627451f,0.2509803922f}; - static constexpr std::array honeydew = {0.9411764706f,1.0f,0.9411764706f}; - static constexpr std::array honeydew1 = honeydew; - static constexpr std::array honeydew2 = {0.8784313725f,0.9333333333f,0.8784313725f}; - static constexpr std::array honeydew3 = {0.7568627451f,0.8039215686f,0.7568627451f}; - static constexpr std::array honeydew4 = {0.5137254902f,0.5450980392f,0.5137254902f}; - static constexpr std::array darkseagreen = {0.5607843137f,0.737254902f,0.5607843137f}; - static constexpr std::array darkseagreen1 = {0.7568627451f,1.0f,0.7568627451f}; - static constexpr std::array darkseagreen2 = {0.7058823529f,0.9333333333f,0.7058823529f}; - static constexpr std::array darkseagreen3 = {0.6078431373f,0.8039215686f,0.6078431373f}; - static constexpr std::array darkseagreen4 = {0.4117647059f,0.5450980392f,0.4117647059f}; - static constexpr std::array palegreen = {0.5960784314f,0.9843137255f,0.5960784314f}; - static constexpr std::array palegreen1 = {0.6039215686f,1.0f,0.6039215686f}; - static constexpr std::array lightgreen = {0.5647058824f,0.9333333333f,0.5647058824f}; - static constexpr std::array palegreen2 = lightgreen; - static constexpr std::array palegreen3 = {0.4862745098f,0.8039215686f,0.4862745098f}; - static constexpr std::array palegreen4 = {0.3294117647f,0.5450980392f,0.3294117647f}; - static constexpr std::array limegreen = {0.1960784314f,0.8039215686f,0.1960784314f}; - static constexpr std::array forestgreen = {0.1333333333f,0.5450980392f,0.1333333333f}; - static constexpr std::array lime = {0.0f,1.0f,0.0f}; - static constexpr std::array green1 = lime; - static constexpr std::array green2 = {0.0f,0.9333333333f,0.0f}; - static constexpr std::array green3 = {0.0f,0.8039215686f,0.0f}; - static constexpr std::array green4 = {0.0f,0.5450980392f,0.0f}; - static constexpr std::array green = {0.0f,0.5019607843f,0.0f}; - static constexpr std::array darkgreen = {0.0f,0.3921568627f,0.0f}; - static constexpr std::array sapgreen = {0.1882352941f,0.5019607843f,0.0784313725f}; - static constexpr std::array lawngreen = {0.4862745098f,0.9882352941f,0.0f}; - static constexpr std::array chartreuse = {0.4980392157f,1.0f,0.0f}; - static constexpr std::array chartreuse1 = chartreuse; - static constexpr std::array chartreuse2 = {0.462745098f,0.9333333333f,0.0f}; - static constexpr std::array chartreuse3 = {0.4f,0.8039215686f,0.0f}; - static constexpr std::array chartreuse4 = {0.2705882353f,0.5450980392f,0.0f}; - static constexpr std::array greenyellow = {0.6784313725f,1.0f,0.1843137255f}; - static constexpr std::array darkolivegreen1 = {0.7921568627f,1.0f,0.4392156863f}; - static constexpr std::array darkolivegreen2 = {0.737254902f,0.9333333333f,0.4078431373f}; - static constexpr std::array darkolivegreen3 = {0.6352941176f,0.8039215686f,0.3529411765f}; - static constexpr std::array darkolivegreen4 = {0.431372549f,0.5450980392f,0.2392156863f}; - static constexpr std::array darkolivegreen = {0.3333333333f,0.4196078431f,0.1843137255f}; - static constexpr std::array olivedrab = {0.4196078431f,0.5568627451f,0.137254902f}; - static constexpr std::array olivedrab1 = {0.7529411765f,1.0f,0.2431372549f}; - static constexpr std::array olivedrab2 = {0.7019607843f,0.9333333333f,0.2274509804f}; - static constexpr std::array olivedrab3 = {0.6039215686f,0.8039215686f,0.1960784314f}; - static constexpr std::array yellowgreen = olivedrab3; - static constexpr std::array olivedrab4 = {0.4117647059f,0.5450980392f,0.1333333333f}; - static constexpr std::array ivory = {1.0f,1.0f,0.9411764706f}; - static constexpr std::array ivory1 = ivory; - static constexpr std::array ivory2 = {0.9333333333f,0.9333333333f,0.8784313725f}; - static constexpr std::array ivory3 = {0.8039215686f,0.8039215686f,0.7568627451f}; - static constexpr std::array ivory4 = {0.5450980392f,0.5450980392f,0.5137254902f}; - static constexpr std::array beige = {0.9607843137f,0.9607843137f,0.862745098f}; - static constexpr std::array lightyellow = {1.0f,1.0f,0.8784313725f}; - static constexpr std::array lightyellow1 = lightyellow; - static constexpr std::array lightyellow2 = {0.9333333333f,0.9333333333f,0.8196078431f}; - static constexpr std::array lightyellow3 = {0.8039215686f,0.8039215686f,0.7058823529f}; - static constexpr std::array lightyellow4 = {0.5450980392f,0.5450980392f,0.4784313725f}; - static constexpr std::array lightgoldenrodyellow = {0.9803921569f,0.9803921569f,0.8235294118f}; - static constexpr std::array yellow = {1.0f,1.0f,0.0f}; - static constexpr std::array yellow1 = yellow; - static constexpr std::array yellow2 = {0.9333333333f,0.9333333333f,0.0f}; - static constexpr std::array yellow3 = {0.8039215686f,0.8039215686f,0.0f}; - static constexpr std::array yellow4 = {0.5450980392f,0.5450980392f,0.0f}; - static constexpr std::array warmgrey = {0.5019607843f,0.5019607843f,0.4117647059f}; - static constexpr std::array olive = {0.5019607843f,0.5019607843f,0.0f}; - static constexpr std::array darkkhaki = {0.7411764706f,0.7176470588f,0.4196078431f}; - static constexpr std::array khaki1 = {1.0f,0.9647058824f,0.5607843137f}; - static constexpr std::array khaki2 = {0.9333333333f,0.9019607843f,0.5215686275f}; - static constexpr std::array khaki3 = {0.8039215686f,0.7764705882f,0.4509803922f}; - static constexpr std::array khaki4 = {0.5450980392f,0.5254901961f,0.3058823529f}; - static constexpr std::array khaki = {0.9411764706f,0.9019607843f,0.5490196078f}; - static constexpr std::array palegoldenrod = {0.9333333333f,0.9098039216f,0.6666666667f}; - static constexpr std::array lemonchiffon = {1.0f,0.9803921569f,0.8039215686f}; - static constexpr std::array lemonchiffon1 = lemonchiffon; - static constexpr std::array lemonchiffon2 = {0.9333333333f,0.9137254902f,0.7490196078f}; - static constexpr std::array lemonchiffon3 = {0.8039215686f,0.7882352941f,0.6470588235f}; - static constexpr std::array lemonchiffon4 = {0.5450980392f,0.537254902f,0.4392156863f}; - static constexpr std::array lightgoldenrod1 = {1.0f,0.9254901961f,0.5450980392f}; - static constexpr std::array lightgoldenrod2 = {0.9333333333f,0.862745098f,0.5098039216f}; - static constexpr std::array lightgoldenrod3 = {0.8039215686f,0.7450980392f,0.4392156863f}; - static constexpr std::array lightgoldenrod4 = {0.5450980392f,0.5058823529f,0.2980392157f}; - static constexpr std::array banana = {0.8901960784f,0.8117647059f,0.3411764706f}; - static constexpr std::array gold = {1.0f,0.8431372549f,0.0f}; - static constexpr std::array gold1 = gold; - static constexpr std::array gold2 = {0.9333333333f,0.7882352941f,0.0f}; - static constexpr std::array gold3 = {0.8039215686f,0.6784313725f,0.0f}; - static constexpr std::array gold4 = {0.5450980392f,0.4588235294f,0.0f}; - static constexpr std::array cornsilk = {1.0f,0.9725490196f,0.862745098f}; - static constexpr std::array cornsilk1 = cornsilk; - static constexpr std::array cornsilk2 = {0.9333333333f,0.9098039216f,0.8039215686f}; - static constexpr std::array cornsilk3 = {0.8039215686f,0.7843137255f,0.6941176471f}; - static constexpr std::array cornsilk4 = {0.5450980392f,0.5333333333f,0.4705882353f}; - static constexpr std::array goldenrod = {0.8549019608f,0.6470588235f,0.1254901961f}; - static constexpr std::array goldenrod1 = {1.0f,0.7568627451f,0.1450980392f}; - static constexpr std::array goldenrod2 = {0.9333333333f,0.7058823529f,0.1333333333f}; - static constexpr std::array goldenrod3 = {0.8039215686f,0.6078431373f,0.1137254902f}; - static constexpr std::array goldenrod4 = {0.5450980392f,0.4117647059f,0.0784313725f}; - static constexpr std::array darkgoldenrod = {0.7215686275f,0.5254901961f,0.0431372549f}; - static constexpr std::array darkgoldenrod1 = {1.0f,0.7254901961f,0.0588235294f}; - static constexpr std::array darkgoldenrod2 = {0.9333333333f,0.6784313725f,0.0549019608f}; - static constexpr std::array darkgoldenrod3 = {0.8039215686f,0.5843137255f,0.0470588235f}; - static constexpr std::array darkgoldenrod4 = {0.5450980392f,0.3960784314f,0.031372549f}; - static constexpr std::array orange = {1.0f,0.5019607843f,0.0f}; - static constexpr std::array orange1 = {1.0f,0.6470588235f,0.0f}; - static constexpr std::array orange2 = {0.9333333333f,0.6039215686f,0.0f}; - static constexpr std::array orange3 = {0.8039215686f,0.5215686275f,0.0f}; - static constexpr std::array orange4 = {0.5450980392f,0.3529411765f,0.0f}; - static constexpr std::array floralwhite = {1.0f,0.9803921569f,0.9411764706f}; - static constexpr std::array oldlace = {0.9921568627f,0.9607843137f,0.9019607843f}; - static constexpr std::array wheat = {0.9607843137f,0.8705882353f,0.7019607843f}; - static constexpr std::array wheat1 = {1.0f,0.9058823529f,0.7294117647f}; - static constexpr std::array wheat2 = {0.9333333333f,0.8470588235f,0.6823529412f}; - static constexpr std::array wheat3 = {0.8039215686f,0.7294117647f,0.5882352941f}; - static constexpr std::array wheat4 = {0.5450980392f,0.4941176471f,0.4f}; - static constexpr std::array moccasin = {1.0f,0.8941176471f,0.7098039216f}; - static constexpr std::array papayawhip = {1.0f,0.937254902f,0.8352941176f}; - static constexpr std::array blanchedalmond = {1.0f,0.9215686275f,0.8039215686f}; - static constexpr std::array navajowhite = {1.0f,0.8705882353f,0.6784313725f}; - static constexpr std::array navajowhite1 = navajowhite; - static constexpr std::array navajowhite2 = {0.9333333333f,0.8117647059f,0.631372549f}; - static constexpr std::array navajowhite3 = {0.8039215686f,0.7019607843f,0.5450980392f}; - static constexpr std::array navajowhite4 = {0.5450980392f,0.4745098039f,0.368627451f}; - static constexpr std::array eggshell = {0.9882352941f,0.9019607843f,0.7882352941f}; - static constexpr std::array brick = {0.6117647059f,0.4f,0.1215686275f}; - static constexpr std::array cadmiumyellow = {1.0f,0.6f,0.0705882353f}; - static constexpr std::array antiquewhite = {0.9803921569f,0.9215686275f,0.8431372549f}; - static constexpr std::array antiquewhite1 = {1.0f,0.937254902f,0.8588235294f}; - static constexpr std::array antiquewhite2 = {0.9333333333f,0.8745098039f,0.8f}; - static constexpr std::array antiquewhite3 = {0.8039215686f,0.7529411765f,0.6901960784f}; - static constexpr std::array antiquewhite4 = {0.5450980392f,0.5137254902f,0.4705882353f}; - static constexpr std::array burlywood = {0.8705882353f,0.7215686275f,0.5294117647f}; - static constexpr std::array burlywood1 = {1.0f,0.8274509804f,0.6078431373f}; - static constexpr std::array burlywood2 = {0.9333333333f,0.7725490196f,0.568627451f}; - static constexpr std::array burlywood3 = {0.8039215686f,0.6666666667f,0.4901960784f}; - static constexpr std::array burlywood4 = {0.5450980392f,0.4509803922f,0.3333333333f}; - static constexpr std::array bisque = {1.0f,0.8941176471f,0.768627451f}; - static constexpr std::array bisque1 = bisque; - static constexpr std::array bisque2 = {0.9333333333f,0.8352941176f,0.7176470588f}; - static constexpr std::array bisque3 = {0.8039215686f,0.7176470588f,0.6196078431f}; - static constexpr std::array bisque4 = {0.5450980392f,0.4901960784f,0.4196078431f}; - static constexpr std::array melon = {0.8901960784f,0.6588235294f,0.4117647059f}; - static constexpr std::array carrot = {0.9294117647f,0.568627451f,0.1294117647f}; - static constexpr std::array darkorange = {1.0f,0.5490196078f,0.0f}; - static constexpr std::array darkorange1 = {1.0f,0.4980392157f,0.0f}; - static constexpr std::array darkorange2 = {0.9333333333f,0.462745098f,0.0f}; - static constexpr std::array darkorange3 = {0.8039215686f,0.4f,0.0f}; - static constexpr std::array darkorange4 = {0.5450980392f,0.2705882353f,0.0f}; - static constexpr std::array tan = {0.8235294118f,0.7058823529f,0.5490196078f}; - static constexpr std::array tan1 = {1.0f,0.6470588235f,0.3098039216f}; - static constexpr std::array tan2 = {0.9333333333f,0.6039215686f,0.2862745098f}; - static constexpr std::array tan3 = {0.8039215686f,0.5215686275f,0.2470588235f}; - static constexpr std::array peru = tan3; - static constexpr std::array tan4 = {0.5450980392f,0.3529411765f,0.168627451f}; - static constexpr std::array linen = {0.9803921569f,0.9411764706f,0.9019607843f}; - static constexpr std::array peachpuff = {1.0f,0.8549019608f,0.7254901961f}; - static constexpr std::array peachpuff1 = peachpuff; - static constexpr std::array peachpuff2 = {0.9333333333f,0.7960784314f,0.6784313725f}; - static constexpr std::array peachpuff3 = {0.8039215686f,0.6862745098f,0.5843137255f}; - static constexpr std::array peachpuff4 = {0.5450980392f,0.4666666667f,0.3960784314f}; - static constexpr std::array seashell = {1.0f,0.9607843137f,0.9333333333f}; - static constexpr std::array seashell1 = seashell; - static constexpr std::array seashell2 = {0.9333333333f,0.8980392157f,0.8705882353f}; - static constexpr std::array seashell3 = {0.8039215686f,0.7725490196f,0.7490196078f}; - static constexpr std::array seashell4 = {0.5450980392f,0.5254901961f,0.5098039216f}; - static constexpr std::array sandybrown = {0.9568627451f,0.6431372549f,0.3764705882f}; - static constexpr std::array rawsienna = {0.7803921569f,0.3803921569f,0.0784313725f}; - static constexpr std::array chocolate = {0.8235294118f,0.4117647059f,0.1176470588f}; - static constexpr std::array chocolate1 = {1.0f,0.4980392157f,0.1411764706f}; - static constexpr std::array chocolate2 = {0.9333333333f,0.462745098f,0.1294117647f}; - static constexpr std::array chocolate3 = {0.8039215686f,0.4f,0.1137254902f}; - static constexpr std::array chocolate4 = {0.5450980392f,0.2705882353f,0.0745098039f}; - static constexpr std::array saddlebrown = chocolate4; - static constexpr std::array ivoryblack = {0.1607843137f,0.1411764706f,0.1294117647f}; - static constexpr std::array flesh = {1.0f,0.4901960784f,0.2509803922f}; - static constexpr std::array cadmiumorange = {1.0f,0.3803921569f,0.0117647059f}; - static constexpr std::array burntsienna = {0.5411764706f,0.2117647059f,0.0588235294f}; - static constexpr std::array sienna = {0.6274509804f,0.3215686275f,0.1764705882f}; - static constexpr std::array sienna1 = {1.0f,0.5098039216f,0.2784313725f}; - static constexpr std::array sienna2 = {0.9333333333f,0.4745098039f,0.2588235294f}; - static constexpr std::array sienna3 = {0.8039215686f,0.4078431373f,0.2235294118f}; - static constexpr std::array sienna4 = {0.5450980392f,0.2784313725f,0.1490196078f}; - static constexpr std::array lightsalmon = {1.0f,0.6274509804f,0.4784313725f}; - static constexpr std::array lightsalmon1 = lightsalmon; - static constexpr std::array lightsalmon2 = {0.9333333333f,0.5843137255f,0.4470588235f}; - static constexpr std::array lightsalmon3 = {0.8039215686f,0.5058823529f,0.3843137255f}; - static constexpr std::array lightsalmon4 = {0.5450980392f,0.3411764706f,0.2588235294f}; - static constexpr std::array coral = {1.0f,0.4980392157f,0.3137254902f}; - static constexpr std::array orangered = {1.0f,0.2705882353f,0.0f}; - static constexpr std::array orangered1 = orangered; - static constexpr std::array orangered2 = {0.9333333333f,0.2509803922f,0.0f}; - static constexpr std::array orangered3 = {0.8039215686f,0.2156862745f,0.0f}; - static constexpr std::array orangered4 = {0.5450980392f,0.1450980392f,0.0f}; - static constexpr std::array sepia = {0.368627451f,0.1490196078f,0.0705882353f}; - static constexpr std::array darksalmon = {0.9137254902f,0.5882352941f,0.4784313725f}; - static constexpr std::array salmon1 = {1.0f,0.5490196078f,0.4117647059f}; - static constexpr std::array salmon2 = {0.9333333333f,0.5098039216f,0.3843137255f}; - static constexpr std::array salmon3 = {0.8039215686f,0.4392156863f,0.3294117647f}; - static constexpr std::array salmon4 = {0.5450980392f,0.2980392157f,0.2235294118f}; - static constexpr std::array coral1 = {1.0f,0.4470588235f,0.337254902f}; - static constexpr std::array coral2 = {0.9333333333f,0.4156862745f,0.3137254902f}; - static constexpr std::array coral3 = {0.8039215686f,0.3568627451f,0.2705882353f}; - static constexpr std::array coral4 = {0.5450980392f,0.2431372549f,0.1843137255f}; - static constexpr std::array burntumber = {0.5411764706f,0.2f,0.1411764706f}; - static constexpr std::array tomato = {1.0f,0.3882352941f,0.2784313725f}; - static constexpr std::array tomato1 = tomato; - static constexpr std::array tomato2 = {0.9333333333f,0.3607843137f,0.2588235294f}; - static constexpr std::array tomato3 = {0.8039215686f,0.3098039216f,0.2235294118f}; - static constexpr std::array tomato4 = {0.5450980392f,0.2117647059f,0.1490196078f}; - static constexpr std::array salmon = {0.9803921569f,0.5019607843f,0.4470588235f}; - static constexpr std::array mistyrose = {1.0f,0.8941176471f,0.8823529412f}; - static constexpr std::array mistyrose1 = mistyrose; - static constexpr std::array mistyrose2 = {0.9333333333f,0.8352941176f,0.8235294118f}; - static constexpr std::array mistyrose3 = {0.8039215686f,0.7176470588f,0.7098039216f}; - static constexpr std::array mistyrose4 = {0.5450980392f,0.4901960784f,0.4823529412f}; - static constexpr std::array snow = {1.0f,0.9803921569f,0.9803921569f}; - static constexpr std::array snow1 = snow; - static constexpr std::array snow2 = {0.9333333333f,0.9137254902f,0.9137254902f}; - static constexpr std::array snow3 = {0.8039215686f,0.7882352941f,0.7882352941f}; - static constexpr std::array snow4 = {0.5450980392f,0.537254902f,0.537254902f}; - static constexpr std::array rosybrown = {0.737254902f,0.5607843137f,0.5607843137f}; - static constexpr std::array rosybrown1 = {1.0f,0.7568627451f,0.7568627451f}; - static constexpr std::array rosybrown2 = {0.9333333333f,0.7058823529f,0.7058823529f}; - static constexpr std::array rosybrown3 = {0.8039215686f,0.6078431373f,0.6078431373f}; - static constexpr std::array rosybrown4 = {0.5450980392f,0.4117647059f,0.4117647059f}; - static constexpr std::array lightcoral = {0.9411764706f,0.5019607843f,0.5019607843f}; - static constexpr std::array indianred = {0.8039215686f,0.3607843137f,0.3607843137f}; - static constexpr std::array indianred1 = {1.0f,0.4156862745f,0.4156862745f}; - static constexpr std::array indianred2 = {0.9333333333f,0.3882352941f,0.3882352941f}; - static constexpr std::array indianred4 = {0.5450980392f,0.2274509804f,0.2274509804f}; - static constexpr std::array indianred3 = {0.8039215686f,0.3333333333f,0.3333333333f}; - static constexpr std::array brown = {0.6470588235f,0.1647058824f,0.1647058824f}; - static constexpr std::array brown1 = {1.0f,0.2509803922f,0.2509803922f}; - static constexpr std::array brown2 = {0.9333333333f,0.231372549f,0.231372549f}; - static constexpr std::array brown3 = {0.8039215686f,0.2f,0.2f}; - static constexpr std::array brown4 = {0.5450980392f,0.137254902f,0.137254902f}; - static constexpr std::array firebrick = {0.6980392157f,0.1333333333f,0.1333333333f}; - static constexpr std::array firebrick1 = {1.0f,0.1882352941f,0.1882352941f}; - static constexpr std::array firebrick2 = {0.9333333333f,0.1725490196f,0.1725490196f}; - static constexpr std::array firebrick3 = {0.8039215686f,0.1490196078f,0.1490196078f}; - static constexpr std::array firebrick4 = {0.5450980392f,0.1019607843f,0.1019607843f}; - static constexpr std::array red = {1.0f,0.0f,0.0f}; - static constexpr std::array red1 = red; - static constexpr std::array red2 = {0.9333333333f,0.0f,0.0f}; - static constexpr std::array red3 = {0.8039215686f,0.0f,0.0f}; - static constexpr std::array red4 = {0.5450980392f,0.0f,0.0f}; - static constexpr std::array darkred = red4; - static constexpr std::array maroon = {0.5019607843f,0.0f,0.0f}; - static constexpr std::array sgi_beet = {0.5568627451f,0.2196078431f,0.5568627451f}; - static constexpr std::array sgi_slateblue = {0.4431372549f,0.4431372549f,0.7764705882f}; - static constexpr std::array sgi_lightblue = {0.4901960784f,0.6196078431f,0.7529411765f}; - static constexpr std::array sgi_teal = {0.2196078431f,0.5568627451f,0.5568627451f}; - static constexpr std::array sgi_chartreuse = {0.4431372549f,0.7764705882f,0.4431372549f}; - static constexpr std::array sgi_olivedrab = {0.5568627451f,0.5568627451f,0.2196078431f}; - static constexpr std::array sgi_brightgray = {0.7725490196f,0.7568627451f,0.6666666667f}; - static constexpr std::array sgi_salmon = {0.7764705882f,0.4431372549f,0.4431372549f}; - static constexpr std::array sgi_darkgray = {0.3333333333f,0.3333333333f,0.3333333333f}; - static constexpr std::array sgi_gray12 = {0.1176470588f,0.1176470588f,0.1176470588f}; - static constexpr std::array sgi_gray16 = {0.1568627451f,0.1568627451f,0.1568627451f}; - static constexpr std::array sgi_gray32 = {0.3176470588f,0.3176470588f,0.3176470588f}; - static constexpr std::array sgi_gray36 = {0.3568627451f,0.3568627451f,0.3568627451f}; - static constexpr std::array sgi_gray52 = {0.5176470588f,0.5176470588f,0.5176470588f}; - static constexpr std::array sgi_gray56 = {0.5568627451f,0.5568627451f,0.5568627451f}; - static constexpr std::array sgi_lightgray = {0.6666666667f,0.6666666667f,0.6666666667f}; - static constexpr std::array sgi_gray72 = {0.7176470588f,0.7176470588f,0.7176470588f}; - static constexpr std::array sgi_gray76 = {0.7568627451f,0.7568627451f,0.7568627451f}; - static constexpr std::array sgi_gray92 = {0.9176470588f,0.9176470588f,0.9176470588f}; - static constexpr std::array sgi_gray96 = {0.9568627451f,0.9568627451f,0.9568627451f}; - static constexpr std::array white = {1.0f,1.0f,1.0f}; - static constexpr std::array white_smoke = {0.9607843137f,0.9607843137f,0.9607843137f}; - static constexpr std::array gainsboro = {0.862745098f,0.862745098f,0.862745098f}; - static constexpr std::array lightgrey = {0.8274509804f,0.8274509804f,0.8274509804f}; - static constexpr std::array silver = {0.7529411765f,0.7529411765f,0.7529411765f}; - static constexpr std::array darkgray = {0.662745098f,0.662745098f,0.662745098f}; - static constexpr std::array gray = {0.5019607843f,0.5019607843f,0.5019607843f}; - static constexpr std::array dimgray = {0.4117647059f,0.4117647059f,0.4117647059f}; - static constexpr std::array black = {0.0f,0.0f,0.0f}; - static constexpr std::array gray99 = {0.9882352941f,0.9882352941f,0.9882352941f}; - static constexpr std::array gray98 = {0.9803921569f,0.9803921569f,0.9803921569f}; - static constexpr std::array gray97 = {0.968627451f,0.968627451f,0.968627451f}; - static constexpr std::array gray96 = {0.9607843137f,0.9607843137f,0.9607843137f}; - static constexpr std::array gray95 = {0.9490196078f,0.9490196078f,0.9490196078f}; - static constexpr std::array gray94 = {0.9411764706f,0.9411764706f,0.9411764706f}; - static constexpr std::array gray93 = {0.9294117647f,0.9294117647f,0.9294117647f}; - static constexpr std::array gray92 = {0.9215686275f,0.9215686275f,0.9215686275f}; - static constexpr std::array gray91 = {0.9098039216f,0.9098039216f,0.9098039216f}; - static constexpr std::array gray90 = {0.8980392157f,0.8980392157f,0.8980392157f}; - static constexpr std::array gray89 = {0.8901960784f,0.8901960784f,0.8901960784f}; - static constexpr std::array gray88 = {0.8784313725f,0.8784313725f,0.8784313725f}; - static constexpr std::array gray87 = {0.8705882353f,0.8705882353f,0.8705882353f}; - static constexpr std::array gray86 = {0.8588235294f,0.8588235294f,0.8588235294f}; - static constexpr std::array gray85 = {0.8509803922f,0.8509803922f,0.8509803922f}; - static constexpr std::array gray84 = {0.8392156863f,0.8392156863f,0.8392156863f}; - static constexpr std::array gray83 = {0.831372549f,0.831372549f,0.831372549f}; - static constexpr std::array gray82 = {0.8196078431f,0.8196078431f,0.8196078431f}; - static constexpr std::array gray81 = {0.8117647059f,0.8117647059f,0.8117647059f}; - static constexpr std::array gray80 = {0.8f,0.8f,0.8f}; - static constexpr std::array gray79 = {0.7882352941f,0.7882352941f,0.7882352941f}; - static constexpr std::array gray78 = {0.7803921569f,0.7803921569f,0.7803921569f}; - static constexpr std::array gray77 = {0.768627451f,0.768627451f,0.768627451f}; - static constexpr std::array gray76 = {0.7607843137f,0.7607843137f,0.7607843137f}; - static constexpr std::array gray75 = {0.7490196078f,0.7490196078f,0.7490196078f}; - static constexpr std::array gray74 = {0.7411764706f,0.7411764706f,0.7411764706f}; - static constexpr std::array gray73 = {0.7294117647f,0.7294117647f,0.7294117647f}; - static constexpr std::array gray72 = {0.7215686275f,0.7215686275f,0.7215686275f}; - static constexpr std::array gray71 = {0.7098039216f,0.7098039216f,0.7098039216f}; - static constexpr std::array gray70 = {0.7019607843f,0.7019607843f,0.7019607843f}; - static constexpr std::array gray69 = {0.6901960784f,0.6901960784f,0.6901960784f}; - static constexpr std::array gray68 = {0.6784313725f,0.6784313725f,0.6784313725f}; - static constexpr std::array gray67 = {0.6705882353f,0.6705882353f,0.6705882353f}; - static constexpr std::array gray66 = {0.6588235294f,0.6588235294f,0.6588235294f}; - static constexpr std::array gray65 = {0.6509803922f,0.6509803922f,0.6509803922f}; - static constexpr std::array gray64 = {0.6392156863f,0.6392156863f,0.6392156863f}; - static constexpr std::array gray63 = {0.631372549f,0.631372549f,0.631372549f}; - static constexpr std::array gray62 = {0.6196078431f,0.6196078431f,0.6196078431f}; - static constexpr std::array gray61 = {0.6117647059f,0.6117647059f,0.6117647059f}; - static constexpr std::array gray60 = {0.6f,0.6f,0.6f}; - static constexpr std::array gray59 = {0.5882352941f,0.5882352941f,0.5882352941f}; - static constexpr std::array gray58 = {0.5803921569f,0.5803921569f,0.5803921569f}; - static constexpr std::array gray57 = {0.568627451f,0.568627451f,0.568627451f}; - static constexpr std::array gray56 = {0.5607843137f,0.5607843137f,0.5607843137f}; - static constexpr std::array gray55 = {0.5490196078f,0.5490196078f,0.5490196078f}; - static constexpr std::array gray54 = {0.5411764706f,0.5411764706f,0.5411764706f}; - static constexpr std::array gray53 = {0.5294117647f,0.5294117647f,0.5294117647f}; - static constexpr std::array gray52 = {0.5215686275f,0.5215686275f,0.5215686275f}; - static constexpr std::array gray51 = {0.5098039216f,0.5098039216f,0.5098039216f}; - static constexpr std::array gray50 = {0.4980392157f,0.4980392157f,0.4980392157f}; - static constexpr std::array gray49 = {0.4901960784f,0.4901960784f,0.4901960784f}; - static constexpr std::array gray48 = {0.4784313725f,0.4784313725f,0.4784313725f}; - static constexpr std::array gray47 = {0.4705882353f,0.4705882353f,0.4705882353f}; - static constexpr std::array gray46 = {0.4588235294f,0.4588235294f,0.4588235294f}; - static constexpr std::array gray45 = {0.4509803922f,0.4509803922f,0.4509803922f}; - static constexpr std::array gray44 = {0.4392156863f,0.4392156863f,0.4392156863f}; - static constexpr std::array gray43 = {0.431372549f,0.431372549f,0.431372549f}; - static constexpr std::array gray42 = {0.4196078431f,0.4196078431f,0.4196078431f}; - static constexpr std::array gray41 = {0.4117647059f,0.4117647059f,0.4117647059f}; - static constexpr std::array gray40 = {0.4f,0.4f,0.4f}; - static constexpr std::array gray39 = {0.3882352941f,0.3882352941f,0.3882352941f}; - static constexpr std::array gray38 = {0.3803921569f,0.3803921569f,0.3803921569f}; - static constexpr std::array gray37 = {0.368627451f,0.368627451f,0.368627451f}; - static constexpr std::array gray36 = {0.3607843137f,0.3607843137f,0.3607843137f}; - static constexpr std::array gray35 = {0.3490196078f,0.3490196078f,0.3490196078f}; - static constexpr std::array gray34 = {0.3411764706f,0.3411764706f,0.3411764706f}; - static constexpr std::array gray33 = {0.3294117647f,0.3294117647f,0.3294117647f}; - static constexpr std::array gray32 = {0.3215686275f,0.3215686275f,0.3215686275f}; - static constexpr std::array gray31 = {0.3098039216f,0.3098039216f,0.3098039216f}; - static constexpr std::array gray30 = {0.3019607843f,0.3019607843f,0.3019607843f}; - static constexpr std::array gray29 = {0.2901960784f,0.2901960784f,0.2901960784f}; - static constexpr std::array gray28 = {0.2784313725f,0.2784313725f,0.2784313725f}; - static constexpr std::array gray27 = {0.2705882353f,0.2705882353f,0.2705882353f}; - static constexpr std::array gray26 = {0.2588235294f,0.2588235294f,0.2588235294f}; - static constexpr std::array gray25 = {0.2509803922f,0.2509803922f,0.2509803922f}; - static constexpr std::array gray24 = {0.2392156863f,0.2392156863f,0.2392156863f}; - static constexpr std::array gray23 = {0.231372549f,0.231372549f,0.231372549f}; - static constexpr std::array gray22 = {0.2196078431f,0.2196078431f,0.2196078431f}; - static constexpr std::array gray21 = {0.2117647059f,0.2117647059f,0.2117647059f}; - static constexpr std::array gray20 = {0.2f,0.2f,0.2f}; - static constexpr std::array gray19 = {0.1882352941f,0.1882352941f,0.1882352941f}; - static constexpr std::array gray18 = {0.1803921569f,0.1803921569f,0.1803921569f}; - static constexpr std::array gray17 = {0.168627451f,0.168627451f,0.168627451f}; - static constexpr std::array gray16 = {0.1607843137f,0.1607843137f,0.1607843137f}; - static constexpr std::array gray15 = {0.1490196078f,0.1490196078f,0.1490196078f}; - static constexpr std::array gray14 = {0.1411764706f,0.1411764706f,0.1411764706f}; - static constexpr std::array gray13 = {0.1294117647f,0.1294117647f,0.1294117647f}; - static constexpr std::array gray12 = {0.1215686275f,0.1215686275f,0.1215686275f}; - static constexpr std::array gray11 = {0.1098039216f,0.1098039216f,0.1098039216f}; - static constexpr std::array gray10 = {0.1019607843f,0.1019607843f,0.1019607843f}; - static constexpr std::array gray9 = {0.0901960784f,0.0901960784f,0.0901960784f}; - static constexpr std::array gray8 = {0.0784313725f,0.0784313725f,0.0784313725f}; - static constexpr std::array gray7 = {0.0705882353f,0.0705882353f,0.0705882353f}; - static constexpr std::array gray6 = {0.0588235294f,0.0588235294f,0.0588235294f}; - static constexpr std::array gray5 = {0.0509803922f,0.0509803922f,0.0509803922f}; - static constexpr std::array gray4 = {0.0392156863f,0.0392156863f,0.0392156863f}; - static constexpr std::array gray3 = {0.031372549f,0.031372549f,0.031372549f}; - static constexpr std::array gray2 = {0.0196078431f,0.0196078431f,0.0196078431f}; - static constexpr std::array gray1 = {0.0117647059f,0.0117647059f,0.0117647059f}; - static constexpr std::array grey99 = {0.9882352941f,0.9882352941f,0.9882352941f}; - static constexpr std::array grey98 = {0.9803921569f,0.9803921569f,0.9803921569f}; - static constexpr std::array grey97 = {0.968627451f,0.968627451f,0.968627451f}; - static constexpr std::array grey96 = {0.9607843137f,0.9607843137f,0.9607843137f}; - static constexpr std::array grey95 = {0.9490196078f,0.9490196078f,0.9490196078f}; - static constexpr std::array grey94 = {0.9411764706f,0.9411764706f,0.9411764706f}; - static constexpr std::array grey93 = {0.9294117647f,0.9294117647f,0.9294117647f}; - static constexpr std::array grey92 = {0.9215686275f,0.9215686275f,0.9215686275f}; - static constexpr std::array grey91 = {0.9098039216f,0.9098039216f,0.9098039216f}; - static constexpr std::array grey90 = {0.8980392157f,0.8980392157f,0.8980392157f}; - static constexpr std::array grey89 = {0.8901960784f,0.8901960784f,0.8901960784f}; - static constexpr std::array grey88 = {0.8784313725f,0.8784313725f,0.8784313725f}; - static constexpr std::array grey87 = {0.8705882353f,0.8705882353f,0.8705882353f}; - static constexpr std::array grey86 = {0.8588235294f,0.8588235294f,0.8588235294f}; - static constexpr std::array grey85 = {0.8509803922f,0.8509803922f,0.8509803922f}; - static constexpr std::array grey84 = {0.8392156863f,0.8392156863f,0.8392156863f}; - static constexpr std::array grey83 = {0.831372549f,0.831372549f,0.831372549f}; - static constexpr std::array grey82 = {0.8196078431f,0.8196078431f,0.8196078431f}; - static constexpr std::array grey81 = {0.8117647059f,0.8117647059f,0.8117647059f}; - static constexpr std::array grey80 = {0.8f,0.8f,0.8f}; - static constexpr std::array grey79 = {0.7882352941f,0.7882352941f,0.7882352941f}; - static constexpr std::array grey78 = {0.7803921569f,0.7803921569f,0.7803921569f}; - static constexpr std::array grey77 = {0.768627451f,0.768627451f,0.768627451f}; - static constexpr std::array grey76 = {0.7607843137f,0.7607843137f,0.7607843137f}; - static constexpr std::array grey75 = {0.7490196078f,0.7490196078f,0.7490196078f}; - static constexpr std::array grey74 = {0.7411764706f,0.7411764706f,0.7411764706f}; - static constexpr std::array grey73 = {0.7294117647f,0.7294117647f,0.7294117647f}; - static constexpr std::array grey72 = {0.7215686275f,0.7215686275f,0.7215686275f}; - static constexpr std::array grey71 = {0.7098039216f,0.7098039216f,0.7098039216f}; - static constexpr std::array grey70 = {0.7019607843f,0.7019607843f,0.7019607843f}; - static constexpr std::array grey69 = {0.6901960784f,0.6901960784f,0.6901960784f}; - static constexpr std::array grey68 = {0.6784313725f,0.6784313725f,0.6784313725f}; - static constexpr std::array grey67 = {0.6705882353f,0.6705882353f,0.6705882353f}; - static constexpr std::array grey66 = {0.6588235294f,0.6588235294f,0.6588235294f}; - static constexpr std::array grey65 = {0.6509803922f,0.6509803922f,0.6509803922f}; - static constexpr std::array grey64 = {0.6392156863f,0.6392156863f,0.6392156863f}; - static constexpr std::array grey63 = {0.631372549f,0.631372549f,0.631372549f}; - static constexpr std::array grey62 = {0.6196078431f,0.6196078431f,0.6196078431f}; - static constexpr std::array grey61 = {0.6117647059f,0.6117647059f,0.6117647059f}; - static constexpr std::array grey60 = {0.6f,0.6f,0.6f}; - static constexpr std::array grey59 = {0.5882352941f,0.5882352941f,0.5882352941f}; - static constexpr std::array grey58 = {0.5803921569f,0.5803921569f,0.5803921569f}; - static constexpr std::array grey57 = {0.568627451f,0.568627451f,0.568627451f}; - static constexpr std::array grey56 = {0.5607843137f,0.5607843137f,0.5607843137f}; - static constexpr std::array grey55 = {0.5490196078f,0.5490196078f,0.5490196078f}; - static constexpr std::array grey54 = {0.5411764706f,0.5411764706f,0.5411764706f}; - static constexpr std::array grey53 = {0.5294117647f,0.5294117647f,0.5294117647f}; - static constexpr std::array grey52 = {0.5215686275f,0.5215686275f,0.5215686275f}; - static constexpr std::array grey51 = {0.5098039216f,0.5098039216f,0.5098039216f}; - static constexpr std::array grey50 = {0.4980392157f,0.4980392157f,0.4980392157f}; - static constexpr std::array grey49 = {0.4901960784f,0.4901960784f,0.4901960784f}; - static constexpr std::array grey48 = {0.4784313725f,0.4784313725f,0.4784313725f}; - static constexpr std::array grey47 = {0.4705882353f,0.4705882353f,0.4705882353f}; - static constexpr std::array grey46 = {0.4588235294f,0.4588235294f,0.4588235294f}; - static constexpr std::array grey45 = {0.4509803922f,0.4509803922f,0.4509803922f}; - static constexpr std::array grey44 = {0.4392156863f,0.4392156863f,0.4392156863f}; - static constexpr std::array grey43 = {0.431372549f,0.431372549f,0.431372549f}; - static constexpr std::array grey42 = {0.4196078431f,0.4196078431f,0.4196078431f}; - static constexpr std::array grey41 = {0.4117647059f,0.4117647059f,0.4117647059f}; - static constexpr std::array grey40 = {0.4f,0.4f,0.4f}; - static constexpr std::array grey39 = {0.3882352941f,0.3882352941f,0.3882352941f}; - static constexpr std::array grey38 = {0.3803921569f,0.3803921569f,0.3803921569f}; - static constexpr std::array grey37 = {0.368627451f,0.368627451f,0.368627451f}; - static constexpr std::array grey36 = {0.3607843137f,0.3607843137f,0.3607843137f}; - static constexpr std::array grey35 = {0.3490196078f,0.3490196078f,0.3490196078f}; - static constexpr std::array grey34 = {0.3411764706f,0.3411764706f,0.3411764706f}; - static constexpr std::array grey33 = {0.3294117647f,0.3294117647f,0.3294117647f}; - static constexpr std::array grey32 = {0.3215686275f,0.3215686275f,0.3215686275f}; - static constexpr std::array grey31 = {0.3098039216f,0.3098039216f,0.3098039216f}; - static constexpr std::array grey30 = {0.3019607843f,0.3019607843f,0.3019607843f}; - static constexpr std::array grey29 = {0.2901960784f,0.2901960784f,0.2901960784f}; - static constexpr std::array grey28 = {0.2784313725f,0.2784313725f,0.2784313725f}; - static constexpr std::array grey27 = {0.2705882353f,0.2705882353f,0.2705882353f}; - static constexpr std::array grey26 = {0.2588235294f,0.2588235294f,0.2588235294f}; - static constexpr std::array grey25 = {0.2509803922f,0.2509803922f,0.2509803922f}; - static constexpr std::array grey24 = {0.2392156863f,0.2392156863f,0.2392156863f}; - static constexpr std::array grey23 = {0.231372549f,0.231372549f,0.231372549f}; - static constexpr std::array grey22 = {0.2196078431f,0.2196078431f,0.2196078431f}; - static constexpr std::array grey21 = {0.2117647059f,0.2117647059f,0.2117647059f}; - static constexpr std::array grey20 = {0.2f,0.2f,0.2f}; - static constexpr std::array grey19 = {0.1882352941f,0.1882352941f,0.1882352941f}; - static constexpr std::array grey18 = {0.1803921569f,0.1803921569f,0.1803921569f}; - static constexpr std::array grey17 = {0.168627451f,0.168627451f,0.168627451f}; - static constexpr std::array grey16 = {0.1607843137f,0.1607843137f,0.1607843137f}; - static constexpr std::array grey15 = {0.1490196078f,0.1490196078f,0.1490196078f}; - static constexpr std::array grey14 = {0.1411764706f,0.1411764706f,0.1411764706f}; - static constexpr std::array grey13 = {0.1294117647f,0.1294117647f,0.1294117647f}; - static constexpr std::array grey12 = {0.1215686275f,0.1215686275f,0.1215686275f}; - static constexpr std::array grey11 = {0.1098039216f,0.1098039216f,0.1098039216f}; - static constexpr std::array grey10 = {0.1019607843f,0.1019607843f,0.1019607843f}; - static constexpr std::array grey9 = {0.0901960784f,0.0901960784f,0.0901960784f}; - static constexpr std::array grey8 = {0.0784313725f,0.0784313725f,0.0784313725f}; - static constexpr std::array grey7 = {0.0705882353f,0.0705882353f,0.0705882353f}; - static constexpr std::array grey6 = {0.0588235294f,0.0588235294f,0.0588235294f}; - static constexpr std::array grey5 = {0.0509803922f,0.0509803922f,0.0509803922f}; - static constexpr std::array grey4 = {0.0392156863f,0.0392156863f,0.0392156863f}; - static constexpr std::array grey3 = {0.031372549f,0.031372549f,0.031372549f}; - static constexpr std::array grey2 = {0.0196078431f,0.0196078431f,0.0196078431f}; - static constexpr std::array grey1 = {0.0117647059f,0.0117647059f,0.0117647059f}; + constexpr std::array indian_red = {0.6901960784f,0.0901960784f,0.1215686275f}; + constexpr std::array crimson = {0.862745098f,0.0784313725f,0.2352941176f}; + constexpr std::array lightpink = {1.0f,0.7137254902f,0.7568627451f}; + constexpr std::array lightpink1 = {1.0f,0.6823529412f,0.7254901961f}; + constexpr std::array lightpink2 = {0.9333333333f,0.6352941176f,0.6784313725f}; + constexpr std::array lightpink3 = {0.8039215686f,0.5490196078f,0.5843137255f}; + constexpr std::array lightpink4 = {0.5450980392f,0.3725490196f,0.3960784314f}; + constexpr std::array pink = {1.0f,0.7529411765f,0.7960784314f}; + constexpr std::array pink1 = {1.0f,0.7098039216f,0.7725490196f}; + constexpr std::array pink2 = {0.9333333333f,0.662745098f,0.7215686275f}; + constexpr std::array pink3 = {0.8039215686f,0.568627451f,0.6196078431f}; + constexpr std::array pink4 = {0.5450980392f,0.3882352941f,0.4235294118f}; + constexpr std::array palevioletred = {0.8588235294f,0.4392156863f,0.5764705882f}; + constexpr std::array palevioletred1 = {1.0f,0.5098039216f,0.6705882353f}; + constexpr std::array palevioletred2 = {0.9333333333f,0.4745098039f,0.6235294118f}; + constexpr std::array palevioletred3 = {0.8039215686f,0.4078431373f,0.537254902f}; + constexpr std::array palevioletred4 = {0.5450980392f,0.2784313725f,0.3647058824f}; + constexpr std::array lavenderblush = {1.0f,0.9411764706f,0.9607843137f}; + constexpr std::array lavenderblush1 = lavenderblush; + constexpr std::array lavenderblush2 = {0.9333333333f,0.8784313725f,0.8980392157f}; + constexpr std::array lavenderblush3 = {0.8039215686f,0.7568627451f,0.7725490196f}; + constexpr std::array lavenderblush4 = {0.5450980392f,0.5137254902f,0.5254901961f}; + constexpr std::array violetred1 = {1.0f,0.2431372549f,0.5882352941f}; + constexpr std::array violetred2 = {0.9333333333f,0.2274509804f,0.5490196078f}; + constexpr std::array violetred3 = {0.8039215686f,0.1960784314f,0.4705882353f}; + constexpr std::array violetred4 = {0.5450980392f,0.1333333333f,0.3215686275f}; + constexpr std::array hotpink = {1.0f,0.4117647059f,0.7058823529f}; + constexpr std::array hotpink1 = {1.0f,0.431372549f,0.7058823529f}; + constexpr std::array hotpink2 = {0.9333333333f,0.4156862745f,0.6549019608f}; + constexpr std::array hotpink3 = {0.8039215686f,0.3764705882f,0.5647058824f}; + constexpr std::array hotpink4 = {0.5450980392f,0.2274509804f,0.3843137255f}; + constexpr std::array raspberry = {0.5294117647f,0.1490196078f,0.3411764706f}; + constexpr std::array deeppink = {1.0f,0.0784313725f,0.5764705882f}; + constexpr std::array deeppink1 = {1.0f,0.0784313725f,0.5764705882f}; + constexpr std::array deeppink2 = {0.9333333333f,0.0705882353f,0.537254902f}; + constexpr std::array deeppink3 = {0.8039215686f,0.062745098f,0.462745098f}; + constexpr std::array deeppink4 = {0.5450980392f,0.0392156863f,0.3137254902f}; + constexpr std::array maroon1 = {1.0f,0.2039215686f,0.7019607843f}; + constexpr std::array maroon2 = {0.9333333333f,0.1882352941f,0.6549019608f}; + constexpr std::array maroon3 = {0.8039215686f,0.1607843137f,0.5647058824f}; + constexpr std::array maroon4 = {0.5450980392f,0.1098039216f,0.3843137255f}; + constexpr std::array mediumvioletred = {0.7803921569f,0.0823529412f,0.5215686275f}; + constexpr std::array violetred = {0.8156862745f,0.1254901961f,0.5647058824f}; + constexpr std::array orchid = {0.8549019608f,0.4392156863f,0.8392156863f}; + constexpr std::array orchid1 = {1.0f,0.5137254902f,0.9803921569f}; + constexpr std::array orchid2 = {0.9333333333f,0.4784313725f,0.9137254902f}; + constexpr std::array orchid3 = {0.8039215686f,0.4117647059f,0.7882352941f}; + constexpr std::array orchid4 = {0.5450980392f,0.2784313725f,0.537254902f}; + constexpr std::array thistle = {0.8470588235f,0.7490196078f,0.8470588235f}; + constexpr std::array thistle1 = {1.0f,0.8823529412f,1.0f}; + constexpr std::array thistle2 = {0.9333333333f,0.8235294118f,0.9333333333f}; + constexpr std::array thistle3 = {0.8039215686f,0.7098039216f,0.8039215686f}; + constexpr std::array thistle4 = {0.5450980392f,0.4823529412f,0.5450980392f}; + constexpr std::array plum1 = {1.0f,0.7333333333f,1.0f}; + constexpr std::array plum2 = {0.9333333333f,0.6823529412f,0.9333333333f}; + constexpr std::array plum3 = {0.8039215686f,0.5882352941f,0.8039215686f}; + constexpr std::array plum4 = {0.5450980392f,0.4f,0.5450980392f}; + constexpr std::array plum = {0.8666666667f,0.6274509804f,0.8666666667f}; + constexpr std::array violet = {0.9333333333f,0.5098039216f,0.9333333333f}; + constexpr std::array magenta = {1.0f,0.0f,1.0f}; + constexpr std::array fuchsia = magenta; + constexpr std::array magenta2 = {0.9333333333f,0.0f,0.9333333333f}; + constexpr std::array magenta3 = {0.8039215686f,0.0f,0.8039215686f}; + constexpr std::array magenta4 = {0.5450980392f,0.0f,0.5450980392f}; + constexpr std::array darkmagenta = magenta4; + constexpr std::array purple = {0.5019607843f,0.0f,0.5019607843f}; + constexpr std::array mediumorchid = {0.7294117647f,0.3333333333f,0.8274509804f}; + constexpr std::array mediumorchid1 = {0.8784313725f,0.4f,1.0f}; + constexpr std::array mediumorchid2 = {0.8196078431f,0.3725490196f,0.9333333333f}; + constexpr std::array mediumorchid3 = {0.7058823529f,0.3215686275f,0.8039215686f}; + constexpr std::array mediumorchid4 = {0.4784313725f,0.2156862745f,0.5450980392f}; + constexpr std::array darkviolet = {0.5803921569f,0.0f,0.8274509804f}; + constexpr std::array darkorchid = {0.6f,0.1960784314f,0.8f}; + constexpr std::array darkorchid1 = {0.7490196078f,0.2431372549f,1.0f}; + constexpr std::array darkorchid2 = {0.6980392157f,0.2274509804f,0.9333333333f}; + constexpr std::array darkorchid3 = {0.6039215686f,0.1960784314f,0.8039215686f}; + constexpr std::array darkorchid4 = {0.4078431373f,0.1333333333f,0.5450980392f}; + constexpr std::array indigo = {0.2941176471f,0.0f,0.5098039216f}; + constexpr std::array blueviolet = {0.5411764706f,0.168627451f,0.8862745098f}; + constexpr std::array purple1 = {0.6078431373f,0.1882352941f,1.0f}; + constexpr std::array purple2 = {0.568627451f,0.1725490196f,0.9333333333f}; + constexpr std::array purple3 = {0.4901960784f,0.1490196078f,0.8039215686f}; + constexpr std::array purple4 = {0.3333333333f,0.1019607843f,0.5450980392f}; + constexpr std::array mediumpurple = {0.5764705882f,0.4392156863f,0.8588235294f}; + constexpr std::array mediumpurple1 = {0.6705882353f,0.5098039216f,1.0f}; + constexpr std::array mediumpurple2 = {0.6235294118f,0.4745098039f,0.9333333333f}; + constexpr std::array mediumpurple3 = {0.537254902f,0.4078431373f,0.8039215686f}; + constexpr std::array mediumpurple4 = {0.3647058824f,0.2784313725f,0.5450980392f}; + constexpr std::array darkslateblue = {0.2823529412f,0.2392156863f,0.5450980392f}; + constexpr std::array lightslateblue = {0.5176470588f,0.4392156863f,1.0f}; + constexpr std::array mediumslateblue = {0.4823529412f,0.4078431373f,0.9333333333f}; + constexpr std::array slateblue = {0.4156862745f,0.3529411765f,0.8039215686f}; + constexpr std::array slateblue1 = {0.5137254902f,0.4352941176f,1.0f}; + constexpr std::array slateblue2 = {0.4784313725f,0.4039215686f,0.9333333333f}; + constexpr std::array slateblue3 = {0.4117647059f,0.3490196078f,0.8039215686f}; + constexpr std::array slateblue4 = {0.2784313725f,0.2352941176f,0.5450980392f}; + constexpr std::array ghostwhite = {0.9725490196f,0.9725490196f,1.0f}; + constexpr std::array lavender = {0.9019607843f,0.9019607843f,0.9803921569f}; + constexpr std::array blue = {0.0f,0.0f,1.0f}; + constexpr std::array blue1 = blue; + constexpr std::array blue2 = {0.0f,0.0f,0.9333333333f}; + constexpr std::array blue3 = {0.0f,0.0f,0.8039215686f}; + constexpr std::array mediumblue = blue3; + constexpr std::array blue4 = {0.0f,0.0f,0.5450980392f}; + constexpr std::array darkblue = blue4; + constexpr std::array navy = {0.0f,0.0f,0.5019607843f}; + constexpr std::array midnightblue = {0.0980392157f,0.0980392157f,0.4392156863f}; + constexpr std::array cobalt = {0.2392156863f,0.3490196078f,0.6705882353f}; + constexpr std::array royalblue = {0.2549019608f,0.4117647059f,0.8823529412f}; + constexpr std::array royalblue1 = {0.2823529412f,0.462745098f,1.0f}; + constexpr std::array royalblue2 = {0.262745098f,0.431372549f,0.9333333333f}; + constexpr std::array royalblue3 = {0.2274509804f,0.3725490196f,0.8039215686f}; + constexpr std::array royalblue4 = {0.1529411765f,0.2509803922f,0.5450980392f}; + constexpr std::array cornflowerblue = {0.3921568627f,0.5843137255f,0.9294117647f}; + constexpr std::array lightsteelblue = {0.6901960784f,0.768627451f,0.8705882353f}; + constexpr std::array lightsteelblue1 = {0.7921568627f,0.8823529412f,1.0f}; + constexpr std::array lightsteelblue2 = {0.737254902f,0.8235294118f,0.9333333333f}; + constexpr std::array lightsteelblue3 = {0.6352941176f,0.7098039216f,0.8039215686f}; + constexpr std::array lightsteelblue4 = {0.431372549f,0.4823529412f,0.5450980392f}; + constexpr std::array lightslategray = {0.4666666667f,0.5333333333f,0.6f}; + constexpr std::array slategray = {0.4392156863f,0.5019607843f,0.5647058824f}; + constexpr std::array slategray1 = {0.7764705882f,0.8862745098f,1.0f}; + constexpr std::array slategray2 = {0.7254901961f,0.8274509804f,0.9333333333f}; + constexpr std::array slategray3 = {0.6235294118f,0.7137254902f,0.8039215686f}; + constexpr std::array slategray4 = {0.4235294118f,0.4823529412f,0.5450980392f}; + constexpr std::array dodgerblue = {0.1176470588f,0.5647058824f,1.0f}; + constexpr std::array dodgerblue1 = dodgerblue; + constexpr std::array dodgerblue2 = {0.1098039216f,0.5254901961f,0.9333333333f}; + constexpr std::array dodgerblue3 = {0.0941176471f,0.4549019608f,0.8039215686f}; + constexpr std::array dodgerblue4 = {0.062745098f,0.3058823529f,0.5450980392f}; + constexpr std::array aliceblue = {0.9411764706f,0.9725490196f,1.0f}; + constexpr std::array steelblue = {0.2745098039f,0.5098039216f,0.7058823529f}; + constexpr std::array steelblue1 = {0.3882352941f,0.7215686275f,1.0f}; + constexpr std::array steelblue2 = {0.3607843137f,0.6745098039f,0.9333333333f}; + constexpr std::array steelblue3 = {0.3098039216f,0.5803921569f,0.8039215686f}; + constexpr std::array steelblue4 = {0.2117647059f,0.3921568627f,0.5450980392f}; + constexpr std::array lightskyblue = {0.5294117647f,0.8078431373f,0.9803921569f}; + constexpr std::array lightskyblue1 = {0.6901960784f,0.8862745098f,1.0f}; + constexpr std::array lightskyblue2 = {0.6431372549f,0.8274509804f,0.9333333333f}; + constexpr std::array lightskyblue3 = {0.5529411765f,0.7137254902f,0.8039215686f}; + constexpr std::array lightskyblue4 = {0.3764705882f,0.4823529412f,0.5450980392f}; + constexpr std::array skyblue = {0.5294117647f,0.8078431373f,0.9215686275f}; + constexpr std::array skyblue1 = {0.5294117647f,0.8078431373f,1.0f}; + constexpr std::array skyblue2 = {0.4941176471f,0.7529411765f,0.9333333333f}; + constexpr std::array skyblue3 = {0.4235294118f,0.6509803922f,0.8039215686f}; + constexpr std::array skyblue4 = {0.2901960784f,0.4392156863f,0.5450980392f}; + constexpr std::array deepskyblue = {0.0f,0.7490196078f,1.0f}; + constexpr std::array deepskyblue1 = deepskyblue; + constexpr std::array deepskyblue2 = {0.0f,0.6980392157f,0.9333333333f}; + constexpr std::array deepskyblue3 = {0.0f,0.6039215686f,0.8039215686f}; + constexpr std::array deepskyblue4 = {0.0f,0.4078431373f,0.5450980392f}; + constexpr std::array peacock = {0.2f,0.631372549f,0.7882352941f}; + constexpr std::array lightblue = {0.6784313725f,0.8470588235f,0.9019607843f}; + constexpr std::array lightblue1 = {0.7490196078f,0.937254902f,1.0f}; + constexpr std::array lightblue2 = {0.6980392157f,0.8745098039f,0.9333333333f}; + constexpr std::array lightblue3 = {0.6039215686f,0.7529411765f,0.8039215686f}; + constexpr std::array lightblue4 = {0.4078431373f,0.5137254902f,0.5450980392f}; + constexpr std::array powderblue = {0.6901960784f,0.8784313725f,0.9019607843f}; + constexpr std::array cadetblue1 = {0.5960784314f,0.9607843137f,1.0f}; + constexpr std::array cadetblue2 = {0.5568627451f,0.8980392157f,0.9333333333f}; + constexpr std::array cadetblue3 = {0.4784313725f,0.7725490196f,0.8039215686f}; + constexpr std::array cadetblue4 = {0.3254901961f,0.5254901961f,0.5450980392f}; + constexpr std::array turquoise1 = {0.0f,0.9607843137f,1.0f}; + constexpr std::array turquoise2 = {0.0f,0.8980392157f,0.9333333333f}; + constexpr std::array turquoise3 = {0.0f,0.7725490196f,0.8039215686f}; + constexpr std::array turquoise4 = {0.0f,0.5254901961f,0.5450980392f}; + constexpr std::array cadetblue = {0.3725490196f,0.6196078431f,0.6274509804f}; + constexpr std::array darkturquoise = {0.0f,0.8078431373f,0.8196078431f}; + constexpr std::array azure = {0.9411764706f,1.0f,1.0f}; + constexpr std::array azure1 = azure; + constexpr std::array azure2 = {0.8784313725f,0.9333333333f,0.9333333333f}; + constexpr std::array azure3 = {0.7568627451f,0.8039215686f,0.8039215686f}; + constexpr std::array azure4 = {0.5137254902f,0.5450980392f,0.5450980392f}; + constexpr std::array lightcyan = {0.8784313725f,1.0f,1.0f}; + constexpr std::array lightcyan1 = lightcyan; + constexpr std::array lightcyan2 = {0.8196078431f,0.9333333333f,0.9333333333f}; + constexpr std::array lightcyan3 = {0.7058823529f,0.8039215686f,0.8039215686f}; + constexpr std::array lightcyan4 = {0.4784313725f,0.5450980392f,0.5450980392f}; + constexpr std::array paleturquoise1 = {0.7333333333f,1.0f,1.0f}; + constexpr std::array paleturquoise = {0.6823529412f,0.9333333333f,0.9333333333f}; + constexpr std::array paleturquoise2 = paleturquoise; + constexpr std::array paleturquoise3 = {0.5882352941f,0.8039215686f,0.8039215686f}; + constexpr std::array paleturquoise4 = {0.4f,0.5450980392f,0.5450980392f}; + constexpr std::array darkslategray = {0.1843137255f,0.3098039216f,0.3098039216f}; + constexpr std::array darkslategray1 = {0.5921568627f,1.0f,1.0f}; + constexpr std::array darkslategray2 = {0.5529411765f,0.9333333333f,0.9333333333f}; + constexpr std::array darkslategray3 = {0.4745098039f,0.8039215686f,0.8039215686f}; + constexpr std::array darkslategray4 = {0.3215686275f,0.5450980392f,0.5450980392f}; + constexpr std::array cyan = {0.0f,1.0f,1.0f}; + constexpr std::array cyan1 = cyan; + constexpr std::array cyan2 = {0.0f,0.9333333333f,0.9333333333f}; + constexpr std::array cyan3 = {0.0f,0.8039215686f,0.8039215686f}; + constexpr std::array cyan4 = {0.0f,0.5450980392f,0.5450980392f}; + constexpr std::array darkcyan = cyan4; + constexpr std::array teal = {0.0f,0.5019607843f,0.5019607843f}; + constexpr std::array mediumturquoise = {0.2823529412f,0.8196078431f,0.8f}; + constexpr std::array lightseagreen = {0.1254901961f,0.6980392157f,0.6666666667f}; + constexpr std::array manganeseblue = {0.0117647059f,0.6588235294f,0.6196078431f}; + constexpr std::array turquoise = {0.2509803922f,0.8784313725f,0.8156862745f}; + constexpr std::array coldgrey = {0.5019607843f,0.5411764706f,0.5294117647f}; + constexpr std::array turquoiseblue = {0.0f,0.7803921569f,0.5490196078f}; + constexpr std::array aquamarine = {0.4980392157f,1.0f,0.831372549f}; + constexpr std::array aquamarine1 = aquamarine; + constexpr std::array aquamarine2 = {0.462745098f,0.9333333333f,0.7764705882f}; + constexpr std::array aquamarine3 = {0.4f,0.8039215686f,0.6666666667f}; + constexpr std::array mediumaquamarine = aquamarine3; + constexpr std::array aquamarine4 = {0.2705882353f,0.5450980392f,0.4549019608f}; + constexpr std::array mediumspringgreen = {0.0f,0.9803921569f,0.6039215686f}; + constexpr std::array mintcream = {0.9607843137f,1.0f,0.9803921569f}; + constexpr std::array springgreen = {0.0f,1.0f,0.4980392157f}; + constexpr std::array springgreen1 = {0.0f,0.9333333333f,0.462745098f}; + constexpr std::array springgreen2 = {0.0f,0.8039215686f,0.4f}; + constexpr std::array springgreen3 = {0.0f,0.5450980392f,0.2705882353f}; + constexpr std::array mediumseagreen = {0.2352941176f,0.7019607843f,0.4431372549f}; + constexpr std::array seagreen1 = {0.3294117647f,1.0f,0.6235294118f}; + constexpr std::array seagreen2 = {0.3058823529f,0.9333333333f,0.5803921569f}; + constexpr std::array seagreen3 = {0.262745098f,0.8039215686f,0.5019607843f}; + constexpr std::array seagreen = {0.1803921569f,0.5450980392f,0.3411764706f}; + constexpr std::array seagreen4 = seagreen; + constexpr std::array emeraldgreen = {0.0f,0.7882352941f,0.3411764706f}; + constexpr std::array mint = {0.7411764706f,0.9882352941f,0.7882352941f}; + constexpr std::array cobaltgreen = {0.2392156863f,0.568627451f,0.2509803922f}; + constexpr std::array honeydew = {0.9411764706f,1.0f,0.9411764706f}; + constexpr std::array honeydew1 = honeydew; + constexpr std::array honeydew2 = {0.8784313725f,0.9333333333f,0.8784313725f}; + constexpr std::array honeydew3 = {0.7568627451f,0.8039215686f,0.7568627451f}; + constexpr std::array honeydew4 = {0.5137254902f,0.5450980392f,0.5137254902f}; + constexpr std::array darkseagreen = {0.5607843137f,0.737254902f,0.5607843137f}; + constexpr std::array darkseagreen1 = {0.7568627451f,1.0f,0.7568627451f}; + constexpr std::array darkseagreen2 = {0.7058823529f,0.9333333333f,0.7058823529f}; + constexpr std::array darkseagreen3 = {0.6078431373f,0.8039215686f,0.6078431373f}; + constexpr std::array darkseagreen4 = {0.4117647059f,0.5450980392f,0.4117647059f}; + constexpr std::array palegreen = {0.5960784314f,0.9843137255f,0.5960784314f}; + constexpr std::array palegreen1 = {0.6039215686f,1.0f,0.6039215686f}; + constexpr std::array lightgreen = {0.5647058824f,0.9333333333f,0.5647058824f}; + constexpr std::array palegreen2 = lightgreen; + constexpr std::array palegreen3 = {0.4862745098f,0.8039215686f,0.4862745098f}; + constexpr std::array palegreen4 = {0.3294117647f,0.5450980392f,0.3294117647f}; + constexpr std::array limegreen = {0.1960784314f,0.8039215686f,0.1960784314f}; + constexpr std::array forestgreen = {0.1333333333f,0.5450980392f,0.1333333333f}; + constexpr std::array lime = {0.0f,1.0f,0.0f}; + constexpr std::array green1 = lime; + constexpr std::array green2 = {0.0f,0.9333333333f,0.0f}; + constexpr std::array green3 = {0.0f,0.8039215686f,0.0f}; + constexpr std::array green4 = {0.0f,0.5450980392f,0.0f}; + constexpr std::array green = {0.0f,0.5019607843f,0.0f}; + constexpr std::array darkgreen = {0.0f,0.3921568627f,0.0f}; + constexpr std::array sapgreen = {0.1882352941f,0.5019607843f,0.0784313725f}; + constexpr std::array lawngreen = {0.4862745098f,0.9882352941f,0.0f}; + constexpr std::array chartreuse = {0.4980392157f,1.0f,0.0f}; + constexpr std::array chartreuse1 = chartreuse; + constexpr std::array chartreuse2 = {0.462745098f,0.9333333333f,0.0f}; + constexpr std::array chartreuse3 = {0.4f,0.8039215686f,0.0f}; + constexpr std::array chartreuse4 = {0.2705882353f,0.5450980392f,0.0f}; + constexpr std::array greenyellow = {0.6784313725f,1.0f,0.1843137255f}; + constexpr std::array darkolivegreen1 = {0.7921568627f,1.0f,0.4392156863f}; + constexpr std::array darkolivegreen2 = {0.737254902f,0.9333333333f,0.4078431373f}; + constexpr std::array darkolivegreen3 = {0.6352941176f,0.8039215686f,0.3529411765f}; + constexpr std::array darkolivegreen4 = {0.431372549f,0.5450980392f,0.2392156863f}; + constexpr std::array darkolivegreen = {0.3333333333f,0.4196078431f,0.1843137255f}; + constexpr std::array olivedrab = {0.4196078431f,0.5568627451f,0.137254902f}; + constexpr std::array olivedrab1 = {0.7529411765f,1.0f,0.2431372549f}; + constexpr std::array olivedrab2 = {0.7019607843f,0.9333333333f,0.2274509804f}; + constexpr std::array olivedrab3 = {0.6039215686f,0.8039215686f,0.1960784314f}; + constexpr std::array yellowgreen = olivedrab3; + constexpr std::array olivedrab4 = {0.4117647059f,0.5450980392f,0.1333333333f}; + constexpr std::array ivory = {1.0f,1.0f,0.9411764706f}; + constexpr std::array ivory1 = ivory; + constexpr std::array ivory2 = {0.9333333333f,0.9333333333f,0.8784313725f}; + constexpr std::array ivory3 = {0.8039215686f,0.8039215686f,0.7568627451f}; + constexpr std::array ivory4 = {0.5450980392f,0.5450980392f,0.5137254902f}; + constexpr std::array beige = {0.9607843137f,0.9607843137f,0.862745098f}; + constexpr std::array lightyellow = {1.0f,1.0f,0.8784313725f}; + constexpr std::array lightyellow1 = lightyellow; + constexpr std::array lightyellow2 = {0.9333333333f,0.9333333333f,0.8196078431f}; + constexpr std::array lightyellow3 = {0.8039215686f,0.8039215686f,0.7058823529f}; + constexpr std::array lightyellow4 = {0.5450980392f,0.5450980392f,0.4784313725f}; + constexpr std::array lightgoldenrodyellow = {0.9803921569f,0.9803921569f,0.8235294118f}; + constexpr std::array yellow = {1.0f,1.0f,0.0f}; + constexpr std::array yellow1 = yellow; + constexpr std::array yellow2 = {0.9333333333f,0.9333333333f,0.0f}; + constexpr std::array yellow3 = {0.8039215686f,0.8039215686f,0.0f}; + constexpr std::array yellow4 = {0.5450980392f,0.5450980392f,0.0f}; + constexpr std::array warmgrey = {0.5019607843f,0.5019607843f,0.4117647059f}; + constexpr std::array olive = {0.5019607843f,0.5019607843f,0.0f}; + constexpr std::array darkkhaki = {0.7411764706f,0.7176470588f,0.4196078431f}; + constexpr std::array khaki1 = {1.0f,0.9647058824f,0.5607843137f}; + constexpr std::array khaki2 = {0.9333333333f,0.9019607843f,0.5215686275f}; + constexpr std::array khaki3 = {0.8039215686f,0.7764705882f,0.4509803922f}; + constexpr std::array khaki4 = {0.5450980392f,0.5254901961f,0.3058823529f}; + constexpr std::array khaki = {0.9411764706f,0.9019607843f,0.5490196078f}; + constexpr std::array palegoldenrod = {0.9333333333f,0.9098039216f,0.6666666667f}; + constexpr std::array lemonchiffon = {1.0f,0.9803921569f,0.8039215686f}; + constexpr std::array lemonchiffon1 = lemonchiffon; + constexpr std::array lemonchiffon2 = {0.9333333333f,0.9137254902f,0.7490196078f}; + constexpr std::array lemonchiffon3 = {0.8039215686f,0.7882352941f,0.6470588235f}; + constexpr std::array lemonchiffon4 = {0.5450980392f,0.537254902f,0.4392156863f}; + constexpr std::array lightgoldenrod1 = {1.0f,0.9254901961f,0.5450980392f}; + constexpr std::array lightgoldenrod2 = {0.9333333333f,0.862745098f,0.5098039216f}; + constexpr std::array lightgoldenrod3 = {0.8039215686f,0.7450980392f,0.4392156863f}; + constexpr std::array lightgoldenrod4 = {0.5450980392f,0.5058823529f,0.2980392157f}; + constexpr std::array banana = {0.8901960784f,0.8117647059f,0.3411764706f}; + constexpr std::array gold = {1.0f,0.8431372549f,0.0f}; + constexpr std::array gold1 = gold; + constexpr std::array gold2 = {0.9333333333f,0.7882352941f,0.0f}; + constexpr std::array gold3 = {0.8039215686f,0.6784313725f,0.0f}; + constexpr std::array gold4 = {0.5450980392f,0.4588235294f,0.0f}; + constexpr std::array cornsilk = {1.0f,0.9725490196f,0.862745098f}; + constexpr std::array cornsilk1 = cornsilk; + constexpr std::array cornsilk2 = {0.9333333333f,0.9098039216f,0.8039215686f}; + constexpr std::array cornsilk3 = {0.8039215686f,0.7843137255f,0.6941176471f}; + constexpr std::array cornsilk4 = {0.5450980392f,0.5333333333f,0.4705882353f}; + constexpr std::array goldenrod = {0.8549019608f,0.6470588235f,0.1254901961f}; + constexpr std::array goldenrod1 = {1.0f,0.7568627451f,0.1450980392f}; + constexpr std::array goldenrod2 = {0.9333333333f,0.7058823529f,0.1333333333f}; + constexpr std::array goldenrod3 = {0.8039215686f,0.6078431373f,0.1137254902f}; + constexpr std::array goldenrod4 = {0.5450980392f,0.4117647059f,0.0784313725f}; + constexpr std::array darkgoldenrod = {0.7215686275f,0.5254901961f,0.0431372549f}; + constexpr std::array darkgoldenrod1 = {1.0f,0.7254901961f,0.0588235294f}; + constexpr std::array darkgoldenrod2 = {0.9333333333f,0.6784313725f,0.0549019608f}; + constexpr std::array darkgoldenrod3 = {0.8039215686f,0.5843137255f,0.0470588235f}; + constexpr std::array darkgoldenrod4 = {0.5450980392f,0.3960784314f,0.031372549f}; + constexpr std::array orange = {1.0f,0.5019607843f,0.0f}; + constexpr std::array orange1 = {1.0f,0.6470588235f,0.0f}; + constexpr std::array orange2 = {0.9333333333f,0.6039215686f,0.0f}; + constexpr std::array orange3 = {0.8039215686f,0.5215686275f,0.0f}; + constexpr std::array orange4 = {0.5450980392f,0.3529411765f,0.0f}; + constexpr std::array floralwhite = {1.0f,0.9803921569f,0.9411764706f}; + constexpr std::array oldlace = {0.9921568627f,0.9607843137f,0.9019607843f}; + constexpr std::array wheat = {0.9607843137f,0.8705882353f,0.7019607843f}; + constexpr std::array wheat1 = {1.0f,0.9058823529f,0.7294117647f}; + constexpr std::array wheat2 = {0.9333333333f,0.8470588235f,0.6823529412f}; + constexpr std::array wheat3 = {0.8039215686f,0.7294117647f,0.5882352941f}; + constexpr std::array wheat4 = {0.5450980392f,0.4941176471f,0.4f}; + constexpr std::array moccasin = {1.0f,0.8941176471f,0.7098039216f}; + constexpr std::array papayawhip = {1.0f,0.937254902f,0.8352941176f}; + constexpr std::array blanchedalmond = {1.0f,0.9215686275f,0.8039215686f}; + constexpr std::array navajowhite = {1.0f,0.8705882353f,0.6784313725f}; + constexpr std::array navajowhite1 = navajowhite; + constexpr std::array navajowhite2 = {0.9333333333f,0.8117647059f,0.631372549f}; + constexpr std::array navajowhite3 = {0.8039215686f,0.7019607843f,0.5450980392f}; + constexpr std::array navajowhite4 = {0.5450980392f,0.4745098039f,0.368627451f}; + constexpr std::array eggshell = {0.9882352941f,0.9019607843f,0.7882352941f}; + constexpr std::array brick = {0.6117647059f,0.4f,0.1215686275f}; + constexpr std::array cadmiumyellow = {1.0f,0.6f,0.0705882353f}; + constexpr std::array antiquewhite = {0.9803921569f,0.9215686275f,0.8431372549f}; + constexpr std::array antiquewhite1 = {1.0f,0.937254902f,0.8588235294f}; + constexpr std::array antiquewhite2 = {0.9333333333f,0.8745098039f,0.8f}; + constexpr std::array antiquewhite3 = {0.8039215686f,0.7529411765f,0.6901960784f}; + constexpr std::array antiquewhite4 = {0.5450980392f,0.5137254902f,0.4705882353f}; + constexpr std::array burlywood = {0.8705882353f,0.7215686275f,0.5294117647f}; + constexpr std::array burlywood1 = {1.0f,0.8274509804f,0.6078431373f}; + constexpr std::array burlywood2 = {0.9333333333f,0.7725490196f,0.568627451f}; + constexpr std::array burlywood3 = {0.8039215686f,0.6666666667f,0.4901960784f}; + constexpr std::array burlywood4 = {0.5450980392f,0.4509803922f,0.3333333333f}; + constexpr std::array bisque = {1.0f,0.8941176471f,0.768627451f}; + constexpr std::array bisque1 = bisque; + constexpr std::array bisque2 = {0.9333333333f,0.8352941176f,0.7176470588f}; + constexpr std::array bisque3 = {0.8039215686f,0.7176470588f,0.6196078431f}; + constexpr std::array bisque4 = {0.5450980392f,0.4901960784f,0.4196078431f}; + constexpr std::array melon = {0.8901960784f,0.6588235294f,0.4117647059f}; + constexpr std::array carrot = {0.9294117647f,0.568627451f,0.1294117647f}; + constexpr std::array darkorange = {1.0f,0.5490196078f,0.0f}; + constexpr std::array darkorange1 = {1.0f,0.4980392157f,0.0f}; + constexpr std::array darkorange2 = {0.9333333333f,0.462745098f,0.0f}; + constexpr std::array darkorange3 = {0.8039215686f,0.4f,0.0f}; + constexpr std::array darkorange4 = {0.5450980392f,0.2705882353f,0.0f}; + constexpr std::array tan = {0.8235294118f,0.7058823529f,0.5490196078f}; + constexpr std::array tan1 = {1.0f,0.6470588235f,0.3098039216f}; + constexpr std::array tan2 = {0.9333333333f,0.6039215686f,0.2862745098f}; + constexpr std::array tan3 = {0.8039215686f,0.5215686275f,0.2470588235f}; + constexpr std::array peru = tan3; + constexpr std::array tan4 = {0.5450980392f,0.3529411765f,0.168627451f}; + constexpr std::array linen = {0.9803921569f,0.9411764706f,0.9019607843f}; + constexpr std::array peachpuff = {1.0f,0.8549019608f,0.7254901961f}; + constexpr std::array peachpuff1 = peachpuff; + constexpr std::array peachpuff2 = {0.9333333333f,0.7960784314f,0.6784313725f}; + constexpr std::array peachpuff3 = {0.8039215686f,0.6862745098f,0.5843137255f}; + constexpr std::array peachpuff4 = {0.5450980392f,0.4666666667f,0.3960784314f}; + constexpr std::array seashell = {1.0f,0.9607843137f,0.9333333333f}; + constexpr std::array seashell1 = seashell; + constexpr std::array seashell2 = {0.9333333333f,0.8980392157f,0.8705882353f}; + constexpr std::array seashell3 = {0.8039215686f,0.7725490196f,0.7490196078f}; + constexpr std::array seashell4 = {0.5450980392f,0.5254901961f,0.5098039216f}; + constexpr std::array sandybrown = {0.9568627451f,0.6431372549f,0.3764705882f}; + constexpr std::array rawsienna = {0.7803921569f,0.3803921569f,0.0784313725f}; + constexpr std::array chocolate = {0.8235294118f,0.4117647059f,0.1176470588f}; + constexpr std::array chocolate1 = {1.0f,0.4980392157f,0.1411764706f}; + constexpr std::array chocolate2 = {0.9333333333f,0.462745098f,0.1294117647f}; + constexpr std::array chocolate3 = {0.8039215686f,0.4f,0.1137254902f}; + constexpr std::array chocolate4 = {0.5450980392f,0.2705882353f,0.0745098039f}; + constexpr std::array saddlebrown = chocolate4; + constexpr std::array ivoryblack = {0.1607843137f,0.1411764706f,0.1294117647f}; + constexpr std::array flesh = {1.0f,0.4901960784f,0.2509803922f}; + constexpr std::array cadmiumorange = {1.0f,0.3803921569f,0.0117647059f}; + constexpr std::array burntsienna = {0.5411764706f,0.2117647059f,0.0588235294f}; + constexpr std::array sienna = {0.6274509804f,0.3215686275f,0.1764705882f}; + constexpr std::array sienna1 = {1.0f,0.5098039216f,0.2784313725f}; + constexpr std::array sienna2 = {0.9333333333f,0.4745098039f,0.2588235294f}; + constexpr std::array sienna3 = {0.8039215686f,0.4078431373f,0.2235294118f}; + constexpr std::array sienna4 = {0.5450980392f,0.2784313725f,0.1490196078f}; + constexpr std::array lightsalmon = {1.0f,0.6274509804f,0.4784313725f}; + constexpr std::array lightsalmon1 = lightsalmon; + constexpr std::array lightsalmon2 = {0.9333333333f,0.5843137255f,0.4470588235f}; + constexpr std::array lightsalmon3 = {0.8039215686f,0.5058823529f,0.3843137255f}; + constexpr std::array lightsalmon4 = {0.5450980392f,0.3411764706f,0.2588235294f}; + constexpr std::array coral = {1.0f,0.4980392157f,0.3137254902f}; + constexpr std::array orangered = {1.0f,0.2705882353f,0.0f}; + constexpr std::array orangered1 = orangered; + constexpr std::array orangered2 = {0.9333333333f,0.2509803922f,0.0f}; + constexpr std::array orangered3 = {0.8039215686f,0.2156862745f,0.0f}; + constexpr std::array orangered4 = {0.5450980392f,0.1450980392f,0.0f}; + constexpr std::array sepia = {0.368627451f,0.1490196078f,0.0705882353f}; + constexpr std::array darksalmon = {0.9137254902f,0.5882352941f,0.4784313725f}; + constexpr std::array salmon1 = {1.0f,0.5490196078f,0.4117647059f}; + constexpr std::array salmon2 = {0.9333333333f,0.5098039216f,0.3843137255f}; + constexpr std::array salmon3 = {0.8039215686f,0.4392156863f,0.3294117647f}; + constexpr std::array salmon4 = {0.5450980392f,0.2980392157f,0.2235294118f}; + constexpr std::array coral1 = {1.0f,0.4470588235f,0.337254902f}; + constexpr std::array coral2 = {0.9333333333f,0.4156862745f,0.3137254902f}; + constexpr std::array coral3 = {0.8039215686f,0.3568627451f,0.2705882353f}; + constexpr std::array coral4 = {0.5450980392f,0.2431372549f,0.1843137255f}; + constexpr std::array burntumber = {0.5411764706f,0.2f,0.1411764706f}; + constexpr std::array tomato = {1.0f,0.3882352941f,0.2784313725f}; + constexpr std::array tomato1 = tomato; + constexpr std::array tomato2 = {0.9333333333f,0.3607843137f,0.2588235294f}; + constexpr std::array tomato3 = {0.8039215686f,0.3098039216f,0.2235294118f}; + constexpr std::array tomato4 = {0.5450980392f,0.2117647059f,0.1490196078f}; + constexpr std::array salmon = {0.9803921569f,0.5019607843f,0.4470588235f}; + constexpr std::array mistyrose = {1.0f,0.8941176471f,0.8823529412f}; + constexpr std::array mistyrose1 = mistyrose; + constexpr std::array mistyrose2 = {0.9333333333f,0.8352941176f,0.8235294118f}; + constexpr std::array mistyrose3 = {0.8039215686f,0.7176470588f,0.7098039216f}; + constexpr std::array mistyrose4 = {0.5450980392f,0.4901960784f,0.4823529412f}; + constexpr std::array snow = {1.0f,0.9803921569f,0.9803921569f}; + constexpr std::array snow1 = snow; + constexpr std::array snow2 = {0.9333333333f,0.9137254902f,0.9137254902f}; + constexpr std::array snow3 = {0.8039215686f,0.7882352941f,0.7882352941f}; + constexpr std::array snow4 = {0.5450980392f,0.537254902f,0.537254902f}; + constexpr std::array rosybrown = {0.737254902f,0.5607843137f,0.5607843137f}; + constexpr std::array rosybrown1 = {1.0f,0.7568627451f,0.7568627451f}; + constexpr std::array rosybrown2 = {0.9333333333f,0.7058823529f,0.7058823529f}; + constexpr std::array rosybrown3 = {0.8039215686f,0.6078431373f,0.6078431373f}; + constexpr std::array rosybrown4 = {0.5450980392f,0.4117647059f,0.4117647059f}; + constexpr std::array lightcoral = {0.9411764706f,0.5019607843f,0.5019607843f}; + constexpr std::array indianred = {0.8039215686f,0.3607843137f,0.3607843137f}; + constexpr std::array indianred1 = {1.0f,0.4156862745f,0.4156862745f}; + constexpr std::array indianred2 = {0.9333333333f,0.3882352941f,0.3882352941f}; + constexpr std::array indianred4 = {0.5450980392f,0.2274509804f,0.2274509804f}; + constexpr std::array indianred3 = {0.8039215686f,0.3333333333f,0.3333333333f}; + constexpr std::array brown = {0.6470588235f,0.1647058824f,0.1647058824f}; + constexpr std::array brown1 = {1.0f,0.2509803922f,0.2509803922f}; + constexpr std::array brown2 = {0.9333333333f,0.231372549f,0.231372549f}; + constexpr std::array brown3 = {0.8039215686f,0.2f,0.2f}; + constexpr std::array brown4 = {0.5450980392f,0.137254902f,0.137254902f}; + constexpr std::array firebrick = {0.6980392157f,0.1333333333f,0.1333333333f}; + constexpr std::array firebrick1 = {1.0f,0.1882352941f,0.1882352941f}; + constexpr std::array firebrick2 = {0.9333333333f,0.1725490196f,0.1725490196f}; + constexpr std::array firebrick3 = {0.8039215686f,0.1490196078f,0.1490196078f}; + constexpr std::array firebrick4 = {0.5450980392f,0.1019607843f,0.1019607843f}; + constexpr std::array red = {1.0f,0.0f,0.0f}; + constexpr std::array red1 = red; + constexpr std::array red2 = {0.9333333333f,0.0f,0.0f}; + constexpr std::array red3 = {0.8039215686f,0.0f,0.0f}; + constexpr std::array red4 = {0.5450980392f,0.0f,0.0f}; + constexpr std::array darkred = red4; + constexpr std::array maroon = {0.5019607843f,0.0f,0.0f}; + constexpr std::array sgi_beet = {0.5568627451f,0.2196078431f,0.5568627451f}; + constexpr std::array sgi_slateblue = {0.4431372549f,0.4431372549f,0.7764705882f}; + constexpr std::array sgi_lightblue = {0.4901960784f,0.6196078431f,0.7529411765f}; + constexpr std::array sgi_teal = {0.2196078431f,0.5568627451f,0.5568627451f}; + constexpr std::array sgi_chartreuse = {0.4431372549f,0.7764705882f,0.4431372549f}; + constexpr std::array sgi_olivedrab = {0.5568627451f,0.5568627451f,0.2196078431f}; + constexpr std::array sgi_brightgray = {0.7725490196f,0.7568627451f,0.6666666667f}; + constexpr std::array sgi_salmon = {0.7764705882f,0.4431372549f,0.4431372549f}; + constexpr std::array sgi_darkgray = {0.3333333333f,0.3333333333f,0.3333333333f}; + constexpr std::array sgi_gray12 = {0.1176470588f,0.1176470588f,0.1176470588f}; + constexpr std::array sgi_gray16 = {0.1568627451f,0.1568627451f,0.1568627451f}; + constexpr std::array sgi_gray32 = {0.3176470588f,0.3176470588f,0.3176470588f}; + constexpr std::array sgi_gray36 = {0.3568627451f,0.3568627451f,0.3568627451f}; + constexpr std::array sgi_gray52 = {0.5176470588f,0.5176470588f,0.5176470588f}; + constexpr std::array sgi_gray56 = {0.5568627451f,0.5568627451f,0.5568627451f}; + constexpr std::array sgi_lightgray = {0.6666666667f,0.6666666667f,0.6666666667f}; + constexpr std::array sgi_gray72 = {0.7176470588f,0.7176470588f,0.7176470588f}; + constexpr std::array sgi_gray76 = {0.7568627451f,0.7568627451f,0.7568627451f}; + constexpr std::array sgi_gray92 = {0.9176470588f,0.9176470588f,0.9176470588f}; + constexpr std::array sgi_gray96 = {0.9568627451f,0.9568627451f,0.9568627451f}; + constexpr std::array white = {1.0f,1.0f,1.0f}; + constexpr std::array white_smoke = {0.9607843137f,0.9607843137f,0.9607843137f}; + constexpr std::array gainsboro = {0.862745098f,0.862745098f,0.862745098f}; + constexpr std::array lightgrey = {0.8274509804f,0.8274509804f,0.8274509804f}; + constexpr std::array silver = {0.7529411765f,0.7529411765f,0.7529411765f}; + constexpr std::array darkgray = {0.662745098f,0.662745098f,0.662745098f}; + constexpr std::array gray = {0.5019607843f,0.5019607843f,0.5019607843f}; + constexpr std::array dimgray = {0.4117647059f,0.4117647059f,0.4117647059f}; + constexpr std::array black = {0.0f,0.0f,0.0f}; + constexpr std::array gray99 = {0.9882352941f,0.9882352941f,0.9882352941f}; + constexpr std::array gray98 = {0.9803921569f,0.9803921569f,0.9803921569f}; + constexpr std::array gray97 = {0.968627451f,0.968627451f,0.968627451f}; + constexpr std::array gray96 = {0.9607843137f,0.9607843137f,0.9607843137f}; + constexpr std::array gray95 = {0.9490196078f,0.9490196078f,0.9490196078f}; + constexpr std::array gray94 = {0.9411764706f,0.9411764706f,0.9411764706f}; + constexpr std::array gray93 = {0.9294117647f,0.9294117647f,0.9294117647f}; + constexpr std::array gray92 = {0.9215686275f,0.9215686275f,0.9215686275f}; + constexpr std::array gray91 = {0.9098039216f,0.9098039216f,0.9098039216f}; + constexpr std::array gray90 = {0.8980392157f,0.8980392157f,0.8980392157f}; + constexpr std::array gray89 = {0.8901960784f,0.8901960784f,0.8901960784f}; + constexpr std::array gray88 = {0.8784313725f,0.8784313725f,0.8784313725f}; + constexpr std::array gray87 = {0.8705882353f,0.8705882353f,0.8705882353f}; + constexpr std::array gray86 = {0.8588235294f,0.8588235294f,0.8588235294f}; + constexpr std::array gray85 = {0.8509803922f,0.8509803922f,0.8509803922f}; + constexpr std::array gray84 = {0.8392156863f,0.8392156863f,0.8392156863f}; + constexpr std::array gray83 = {0.831372549f,0.831372549f,0.831372549f}; + constexpr std::array gray82 = {0.8196078431f,0.8196078431f,0.8196078431f}; + constexpr std::array gray81 = {0.8117647059f,0.8117647059f,0.8117647059f}; + constexpr std::array gray80 = {0.8f,0.8f,0.8f}; + constexpr std::array gray79 = {0.7882352941f,0.7882352941f,0.7882352941f}; + constexpr std::array gray78 = {0.7803921569f,0.7803921569f,0.7803921569f}; + constexpr std::array gray77 = {0.768627451f,0.768627451f,0.768627451f}; + constexpr std::array gray76 = {0.7607843137f,0.7607843137f,0.7607843137f}; + constexpr std::array gray75 = {0.7490196078f,0.7490196078f,0.7490196078f}; + constexpr std::array gray74 = {0.7411764706f,0.7411764706f,0.7411764706f}; + constexpr std::array gray73 = {0.7294117647f,0.7294117647f,0.7294117647f}; + constexpr std::array gray72 = {0.7215686275f,0.7215686275f,0.7215686275f}; + constexpr std::array gray71 = {0.7098039216f,0.7098039216f,0.7098039216f}; + constexpr std::array gray70 = {0.7019607843f,0.7019607843f,0.7019607843f}; + constexpr std::array gray69 = {0.6901960784f,0.6901960784f,0.6901960784f}; + constexpr std::array gray68 = {0.6784313725f,0.6784313725f,0.6784313725f}; + constexpr std::array gray67 = {0.6705882353f,0.6705882353f,0.6705882353f}; + constexpr std::array gray66 = {0.6588235294f,0.6588235294f,0.6588235294f}; + constexpr std::array gray65 = {0.6509803922f,0.6509803922f,0.6509803922f}; + constexpr std::array gray64 = {0.6392156863f,0.6392156863f,0.6392156863f}; + constexpr std::array gray63 = {0.631372549f,0.631372549f,0.631372549f}; + constexpr std::array gray62 = {0.6196078431f,0.6196078431f,0.6196078431f}; + constexpr std::array gray61 = {0.6117647059f,0.6117647059f,0.6117647059f}; + constexpr std::array gray60 = {0.6f,0.6f,0.6f}; + constexpr std::array gray59 = {0.5882352941f,0.5882352941f,0.5882352941f}; + constexpr std::array gray58 = {0.5803921569f,0.5803921569f,0.5803921569f}; + constexpr std::array gray57 = {0.568627451f,0.568627451f,0.568627451f}; + constexpr std::array gray56 = {0.5607843137f,0.5607843137f,0.5607843137f}; + constexpr std::array gray55 = {0.5490196078f,0.5490196078f,0.5490196078f}; + constexpr std::array gray54 = {0.5411764706f,0.5411764706f,0.5411764706f}; + constexpr std::array gray53 = {0.5294117647f,0.5294117647f,0.5294117647f}; + constexpr std::array gray52 = {0.5215686275f,0.5215686275f,0.5215686275f}; + constexpr std::array gray51 = {0.5098039216f,0.5098039216f,0.5098039216f}; + constexpr std::array gray50 = {0.4980392157f,0.4980392157f,0.4980392157f}; + constexpr std::array gray49 = {0.4901960784f,0.4901960784f,0.4901960784f}; + constexpr std::array gray48 = {0.4784313725f,0.4784313725f,0.4784313725f}; + constexpr std::array gray47 = {0.4705882353f,0.4705882353f,0.4705882353f}; + constexpr std::array gray46 = {0.4588235294f,0.4588235294f,0.4588235294f}; + constexpr std::array gray45 = {0.4509803922f,0.4509803922f,0.4509803922f}; + constexpr std::array gray44 = {0.4392156863f,0.4392156863f,0.4392156863f}; + constexpr std::array gray43 = {0.431372549f,0.431372549f,0.431372549f}; + constexpr std::array gray42 = {0.4196078431f,0.4196078431f,0.4196078431f}; + constexpr std::array gray41 = {0.4117647059f,0.4117647059f,0.4117647059f}; + constexpr std::array gray40 = {0.4f,0.4f,0.4f}; + constexpr std::array gray39 = {0.3882352941f,0.3882352941f,0.3882352941f}; + constexpr std::array gray38 = {0.3803921569f,0.3803921569f,0.3803921569f}; + constexpr std::array gray37 = {0.368627451f,0.368627451f,0.368627451f}; + constexpr std::array gray36 = {0.3607843137f,0.3607843137f,0.3607843137f}; + constexpr std::array gray35 = {0.3490196078f,0.3490196078f,0.3490196078f}; + constexpr std::array gray34 = {0.3411764706f,0.3411764706f,0.3411764706f}; + constexpr std::array gray33 = {0.3294117647f,0.3294117647f,0.3294117647f}; + constexpr std::array gray32 = {0.3215686275f,0.3215686275f,0.3215686275f}; + constexpr std::array gray31 = {0.3098039216f,0.3098039216f,0.3098039216f}; + constexpr std::array gray30 = {0.3019607843f,0.3019607843f,0.3019607843f}; + constexpr std::array gray29 = {0.2901960784f,0.2901960784f,0.2901960784f}; + constexpr std::array gray28 = {0.2784313725f,0.2784313725f,0.2784313725f}; + constexpr std::array gray27 = {0.2705882353f,0.2705882353f,0.2705882353f}; + constexpr std::array gray26 = {0.2588235294f,0.2588235294f,0.2588235294f}; + constexpr std::array gray25 = {0.2509803922f,0.2509803922f,0.2509803922f}; + constexpr std::array gray24 = {0.2392156863f,0.2392156863f,0.2392156863f}; + constexpr std::array gray23 = {0.231372549f,0.231372549f,0.231372549f}; + constexpr std::array gray22 = {0.2196078431f,0.2196078431f,0.2196078431f}; + constexpr std::array gray21 = {0.2117647059f,0.2117647059f,0.2117647059f}; + constexpr std::array gray20 = {0.2f,0.2f,0.2f}; + constexpr std::array gray19 = {0.1882352941f,0.1882352941f,0.1882352941f}; + constexpr std::array gray18 = {0.1803921569f,0.1803921569f,0.1803921569f}; + constexpr std::array gray17 = {0.168627451f,0.168627451f,0.168627451f}; + constexpr std::array gray16 = {0.1607843137f,0.1607843137f,0.1607843137f}; + constexpr std::array gray15 = {0.1490196078f,0.1490196078f,0.1490196078f}; + constexpr std::array gray14 = {0.1411764706f,0.1411764706f,0.1411764706f}; + constexpr std::array gray13 = {0.1294117647f,0.1294117647f,0.1294117647f}; + constexpr std::array gray12 = {0.1215686275f,0.1215686275f,0.1215686275f}; + constexpr std::array gray11 = {0.1098039216f,0.1098039216f,0.1098039216f}; + constexpr std::array gray10 = {0.1019607843f,0.1019607843f,0.1019607843f}; + constexpr std::array gray9 = {0.0901960784f,0.0901960784f,0.0901960784f}; + constexpr std::array gray8 = {0.0784313725f,0.0784313725f,0.0784313725f}; + constexpr std::array gray7 = {0.0705882353f,0.0705882353f,0.0705882353f}; + constexpr std::array gray6 = {0.0588235294f,0.0588235294f,0.0588235294f}; + constexpr std::array gray5 = {0.0509803922f,0.0509803922f,0.0509803922f}; + constexpr std::array gray4 = {0.0392156863f,0.0392156863f,0.0392156863f}; + constexpr std::array gray3 = {0.031372549f,0.031372549f,0.031372549f}; + constexpr std::array gray2 = {0.0196078431f,0.0196078431f,0.0196078431f}; + constexpr std::array gray1 = {0.0117647059f,0.0117647059f,0.0117647059f}; + constexpr std::array grey99 = {0.9882352941f,0.9882352941f,0.9882352941f}; + constexpr std::array grey98 = {0.9803921569f,0.9803921569f,0.9803921569f}; + constexpr std::array grey97 = {0.968627451f,0.968627451f,0.968627451f}; + constexpr std::array grey96 = {0.9607843137f,0.9607843137f,0.9607843137f}; + constexpr std::array grey95 = {0.9490196078f,0.9490196078f,0.9490196078f}; + constexpr std::array grey94 = {0.9411764706f,0.9411764706f,0.9411764706f}; + constexpr std::array grey93 = {0.9294117647f,0.9294117647f,0.9294117647f}; + constexpr std::array grey92 = {0.9215686275f,0.9215686275f,0.9215686275f}; + constexpr std::array grey91 = {0.9098039216f,0.9098039216f,0.9098039216f}; + constexpr std::array grey90 = {0.8980392157f,0.8980392157f,0.8980392157f}; + constexpr std::array grey89 = {0.8901960784f,0.8901960784f,0.8901960784f}; + constexpr std::array grey88 = {0.8784313725f,0.8784313725f,0.8784313725f}; + constexpr std::array grey87 = {0.8705882353f,0.8705882353f,0.8705882353f}; + constexpr std::array grey86 = {0.8588235294f,0.8588235294f,0.8588235294f}; + constexpr std::array grey85 = {0.8509803922f,0.8509803922f,0.8509803922f}; + constexpr std::array grey84 = {0.8392156863f,0.8392156863f,0.8392156863f}; + constexpr std::array grey83 = {0.831372549f,0.831372549f,0.831372549f}; + constexpr std::array grey82 = {0.8196078431f,0.8196078431f,0.8196078431f}; + constexpr std::array grey81 = {0.8117647059f,0.8117647059f,0.8117647059f}; + constexpr std::array grey80 = {0.8f,0.8f,0.8f}; + constexpr std::array grey79 = {0.7882352941f,0.7882352941f,0.7882352941f}; + constexpr std::array grey78 = {0.7803921569f,0.7803921569f,0.7803921569f}; + constexpr std::array grey77 = {0.768627451f,0.768627451f,0.768627451f}; + constexpr std::array grey76 = {0.7607843137f,0.7607843137f,0.7607843137f}; + constexpr std::array grey75 = {0.7490196078f,0.7490196078f,0.7490196078f}; + constexpr std::array grey74 = {0.7411764706f,0.7411764706f,0.7411764706f}; + constexpr std::array grey73 = {0.7294117647f,0.7294117647f,0.7294117647f}; + constexpr std::array grey72 = {0.7215686275f,0.7215686275f,0.7215686275f}; + constexpr std::array grey71 = {0.7098039216f,0.7098039216f,0.7098039216f}; + constexpr std::array grey70 = {0.7019607843f,0.7019607843f,0.7019607843f}; + constexpr std::array grey69 = {0.6901960784f,0.6901960784f,0.6901960784f}; + constexpr std::array grey68 = {0.6784313725f,0.6784313725f,0.6784313725f}; + constexpr std::array grey67 = {0.6705882353f,0.6705882353f,0.6705882353f}; + constexpr std::array grey66 = {0.6588235294f,0.6588235294f,0.6588235294f}; + constexpr std::array grey65 = {0.6509803922f,0.6509803922f,0.6509803922f}; + constexpr std::array grey64 = {0.6392156863f,0.6392156863f,0.6392156863f}; + constexpr std::array grey63 = {0.631372549f,0.631372549f,0.631372549f}; + constexpr std::array grey62 = {0.6196078431f,0.6196078431f,0.6196078431f}; + constexpr std::array grey61 = {0.6117647059f,0.6117647059f,0.6117647059f}; + constexpr std::array grey60 = {0.6f,0.6f,0.6f}; + constexpr std::array grey59 = {0.5882352941f,0.5882352941f,0.5882352941f}; + constexpr std::array grey58 = {0.5803921569f,0.5803921569f,0.5803921569f}; + constexpr std::array grey57 = {0.568627451f,0.568627451f,0.568627451f}; + constexpr std::array grey56 = {0.5607843137f,0.5607843137f,0.5607843137f}; + constexpr std::array grey55 = {0.5490196078f,0.5490196078f,0.5490196078f}; + constexpr std::array grey54 = {0.5411764706f,0.5411764706f,0.5411764706f}; + constexpr std::array grey53 = {0.5294117647f,0.5294117647f,0.5294117647f}; + constexpr std::array grey52 = {0.5215686275f,0.5215686275f,0.5215686275f}; + constexpr std::array grey51 = {0.5098039216f,0.5098039216f,0.5098039216f}; + constexpr std::array grey50 = {0.4980392157f,0.4980392157f,0.4980392157f}; + constexpr std::array grey49 = {0.4901960784f,0.4901960784f,0.4901960784f}; + constexpr std::array grey48 = {0.4784313725f,0.4784313725f,0.4784313725f}; + constexpr std::array grey47 = {0.4705882353f,0.4705882353f,0.4705882353f}; + constexpr std::array grey46 = {0.4588235294f,0.4588235294f,0.4588235294f}; + constexpr std::array grey45 = {0.4509803922f,0.4509803922f,0.4509803922f}; + constexpr std::array grey44 = {0.4392156863f,0.4392156863f,0.4392156863f}; + constexpr std::array grey43 = {0.431372549f,0.431372549f,0.431372549f}; + constexpr std::array grey42 = {0.4196078431f,0.4196078431f,0.4196078431f}; + constexpr std::array grey41 = {0.4117647059f,0.4117647059f,0.4117647059f}; + constexpr std::array grey40 = {0.4f,0.4f,0.4f}; + constexpr std::array grey39 = {0.3882352941f,0.3882352941f,0.3882352941f}; + constexpr std::array grey38 = {0.3803921569f,0.3803921569f,0.3803921569f}; + constexpr std::array grey37 = {0.368627451f,0.368627451f,0.368627451f}; + constexpr std::array grey36 = {0.3607843137f,0.3607843137f,0.3607843137f}; + constexpr std::array grey35 = {0.3490196078f,0.3490196078f,0.3490196078f}; + constexpr std::array grey34 = {0.3411764706f,0.3411764706f,0.3411764706f}; + constexpr std::array grey33 = {0.3294117647f,0.3294117647f,0.3294117647f}; + constexpr std::array grey32 = {0.3215686275f,0.3215686275f,0.3215686275f}; + constexpr std::array grey31 = {0.3098039216f,0.3098039216f,0.3098039216f}; + constexpr std::array grey30 = {0.3019607843f,0.3019607843f,0.3019607843f}; + constexpr std::array grey29 = {0.2901960784f,0.2901960784f,0.2901960784f}; + constexpr std::array grey28 = {0.2784313725f,0.2784313725f,0.2784313725f}; + constexpr std::array grey27 = {0.2705882353f,0.2705882353f,0.2705882353f}; + constexpr std::array grey26 = {0.2588235294f,0.2588235294f,0.2588235294f}; + constexpr std::array grey25 = {0.2509803922f,0.2509803922f,0.2509803922f}; + constexpr std::array grey24 = {0.2392156863f,0.2392156863f,0.2392156863f}; + constexpr std::array grey23 = {0.231372549f,0.231372549f,0.231372549f}; + constexpr std::array grey22 = {0.2196078431f,0.2196078431f,0.2196078431f}; + constexpr std::array grey21 = {0.2117647059f,0.2117647059f,0.2117647059f}; + constexpr std::array grey20 = {0.2f,0.2f,0.2f}; + constexpr std::array grey19 = {0.1882352941f,0.1882352941f,0.1882352941f}; + constexpr std::array grey18 = {0.1803921569f,0.1803921569f,0.1803921569f}; + constexpr std::array grey17 = {0.168627451f,0.168627451f,0.168627451f}; + constexpr std::array grey16 = {0.1607843137f,0.1607843137f,0.1607843137f}; + constexpr std::array grey15 = {0.1490196078f,0.1490196078f,0.1490196078f}; + constexpr std::array grey14 = {0.1411764706f,0.1411764706f,0.1411764706f}; + constexpr std::array grey13 = {0.1294117647f,0.1294117647f,0.1294117647f}; + constexpr std::array grey12 = {0.1215686275f,0.1215686275f,0.1215686275f}; + constexpr std::array grey11 = {0.1098039216f,0.1098039216f,0.1098039216f}; + constexpr std::array grey10 = {0.1019607843f,0.1019607843f,0.1019607843f}; + constexpr std::array grey9 = {0.0901960784f,0.0901960784f,0.0901960784f}; + constexpr std::array grey8 = {0.0784313725f,0.0784313725f,0.0784313725f}; + constexpr std::array grey7 = {0.0705882353f,0.0705882353f,0.0705882353f}; + constexpr std::array grey6 = {0.0588235294f,0.0588235294f,0.0588235294f}; + constexpr std::array grey5 = {0.0509803922f,0.0509803922f,0.0509803922f}; + constexpr std::array grey4 = {0.0392156863f,0.0392156863f,0.0392156863f}; + constexpr std::array grey3 = {0.031372549f,0.031372549f,0.031372549f}; + constexpr std::array grey2 = {0.0196078431f,0.0196078431f,0.0196078431f}; + constexpr std::array grey1 = {0.0117647059f,0.0117647059f,0.0117647059f}; } diff --git a/mplot/core.ixx b/mplot/core.ixx deleted file mode 100644 index fb9867ea..00000000 --- a/mplot/core.ixx +++ /dev/null @@ -1,2 +0,0 @@ -export module mplot.core; -export import :visual; diff --git a/mplot/gl/version.h b/mplot/gl/version.h index 4d5cb2ca..6f766f6a 100644 --- a/mplot/gl/version.h +++ b/mplot/gl/version.h @@ -1,5 +1,3 @@ -#pragma once - /*! * \file * @@ -8,10 +6,12 @@ * \author Seb James * \date January 2024 */ - +module; #include -namespace mplot::gl +export module mplot.gl.version; + +export namespace mplot::gl { //!@{ /*! @@ -19,21 +19,21 @@ namespace mplot::gl * argument to mplot::Visual and friends. These are the human-readable definitions. You can * pass, for example `mplot::gl::version_4_3` as the argument to your template. */ - static constexpr int version_4_1 = 0x00040001; - static constexpr int version_4_1_compat = 0x20040001; - static constexpr int version_4_2 = 0x00040002; - static constexpr int version_4_2_compat = 0x20040002; - static constexpr int version_4_3 = 0x00040003; - static constexpr int version_4_3_compat = 0x20040003; - static constexpr int version_4_4 = 0x00040004; - static constexpr int version_4_4_compat = 0x20040004; - static constexpr int version_4_5 = 0x00040005; - static constexpr int version_4_5_compat = 0x20040005; - static constexpr int version_4_6 = 0x00040006; - static constexpr int version_4_6_compat = 0x20040006; - static constexpr int version_3_0_es = 0x40030000; // OpenGL 3.0 ES is a subset of OpenGL 3.3 - static constexpr int version_3_1_es = 0x40030001; // OpenGL 3.1 ES is a subset of OpenGL 4.3 - static constexpr int version_3_2_es = 0x40030002; + constexpr int version_4_1 = 0x00040001; + constexpr int version_4_1_compat = 0x20040001; + constexpr int version_4_2 = 0x00040002; + constexpr int version_4_2_compat = 0x20040002; + constexpr int version_4_3 = 0x00040003; + constexpr int version_4_3_compat = 0x20040003; + constexpr int version_4_4 = 0x00040004; + constexpr int version_4_4_compat = 0x20040004; + constexpr int version_4_5 = 0x00040005; + constexpr int version_4_5_compat = 0x20040005; + constexpr int version_4_6 = 0x00040006; + constexpr int version_4_6_compat = 0x20040006; + constexpr int version_3_0_es = 0x40030000; // OpenGL 3.0 ES is a subset of OpenGL 3.3 + constexpr int version_3_1_es = 0x40030001; // OpenGL 3.1 ES is a subset of OpenGL 4.3 + constexpr int version_3_2_es = 0x40030002; //!@{ /* @@ -47,27 +47,27 @@ namespace mplot::gl namespace version { // Open GL minor version number - static int constexpr minor (const int gl_version_number) + int constexpr minor (const int gl_version_number) { return (gl_version_number & 0xffff); } // Open GL major version number - static int constexpr major (const int gl_version_number) + int constexpr major (const int gl_version_number) { return (gl_version_number >> 16 & 0x1fff); } // True if this is the compatibility profile (by default it's the core profile) - static bool constexpr compat (const int gl_version_number) + bool constexpr compat (const int gl_version_number) { return (((gl_version_number >> 29) & 0x1) > 0x0) ? true : false; } // True if this is an OpenGL ES version - static bool constexpr gles (const int gl_version_number) + bool constexpr gles (const int gl_version_number) { return (((gl_version_number >> 30) & 0x1) > 0x0) ? true : false; } // True if this version suports shader storage buffer objects - static bool constexpr has_ssbo (const int gl_version_number) + bool constexpr has_ssbo (const int gl_version_number) { if (mplot::gl::version::gles (gl_version_number) == true) { // OpenGL ES 3.1 and up supports SSBO @@ -82,7 +82,7 @@ namespace mplot::gl } } // Output a string describing the version number - static inline std::string vstring (const int gl_version_number) + inline std::string vstring (const int gl_version_number) { std::string v = std::to_string (version::major(gl_version_number)) + std::string(".") + std::to_string (version::minor(gl_version_number)); @@ -95,7 +95,7 @@ namespace mplot::gl return v; } // Return the version-specific shader preamble as a const char* from a constexpr function - static constexpr const char* shaderpreamble (const int gl_version_number) + constexpr const char* shaderpreamble (const int gl_version_number) { const char* preamble = "#version unknown\n"; From 679c6e6af21ee68afdcf01845e2eb554e0a87ba7 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 6 Mar 2026 19:20:17 +0000 Subject: [PATCH 023/106] Clang23 now builds both helloworld AND rod! --- examples/CMakeLists.txt | 11 +++++++++++ examples/rod.cpp | 11 ++++++++--- maths | 2 +- mplot/ColourMap.h | 2 +- mplot/CoordArrows.h | 3 +-- mplot/NavMesh.h | 3 +-- mplot/RodVisual.h | 3 ++- mplot/VisualCommon.h | 3 ++- mplot/VisualFace.h | 3 +-- mplot/VisualModel.h | 39 ++++++++++++++++----------------------- mplot/VisualOwnable.h | 9 ++++++--- mplot/VisualResources.h | 3 +-- mplot/VisualTextModel.h | 2 +- mplot/gl/loadshaders_mx.h | 3 ++- mplot/gl/ssbo_mx.h | 2 +- mplot/gl/util_mx.h | 13 ++++++++++--- mplot/tools.h | 14 ++++++++------ 17 files changed, 73 insertions(+), 53 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index bc88b2ab..a50c58b6 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -25,6 +25,8 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra ${PROJECT_SOURCE_DIR}/maths/sm/flags ${PROJECT_SOURCE_DIR}/maths/sm/centroid + ${PROJECT_SOURCE_DIR}/maths/sm/util + ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h ${PROJECT_SOURCE_DIR}/mplot/Visual.h ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h @@ -38,14 +40,18 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h ${PROJECT_SOURCE_DIR}/mplot/win_t.h ${PROJECT_SOURCE_DIR}/mplot/colour.h + ${PROJECT_SOURCE_DIR}/mplot/tools.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h + ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h PROPERTIES LANGUAGE CXX ) add_executable(helloworld helloworld.cpp) target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES + ${PROJECT_SOURCE_DIR}/mplot/tools.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h + ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h ${PROJECT_SOURCE_DIR}/mplot/colour.h ${PROJECT_SOURCE_DIR}/mplot/win_t.h ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h @@ -59,6 +65,7 @@ target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/maths/sm/flags ${PROJECT_SOURCE_DIR}/maths/sm/algo ${PROJECT_SOURCE_DIR}/maths/sm/range @@ -74,7 +81,9 @@ target_link_libraries(helloworld OpenGL::GL glfw Freetype::Freetype glad mplot_f add_executable(rod rod.cpp) target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES + ${PROJECT_SOURCE_DIR}/mplot/tools.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h + ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h ${PROJECT_SOURCE_DIR}/mplot/colour.h ${PROJECT_SOURCE_DIR}/mplot/win_t.h ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h @@ -88,6 +97,8 @@ target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/maths/sm/util + ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/maths/sm/flags ${PROJECT_SOURCE_DIR}/maths/sm/algo ${PROJECT_SOURCE_DIR}/maths/sm/range diff --git a/examples/rod.cpp b/examples/rod.cpp index 28d7cd31..7e9ecfc6 100644 --- a/examples/rod.cpp +++ b/examples/rod.cpp @@ -2,13 +2,14 @@ * Visualize a Rod */ #include +#include import mplot.visual; import mplot.gl.version; #include -//#include // import mplot.gridvisual; +#include // import mplot.gridvisual; import sm.vec; @@ -28,20 +29,24 @@ int main() constexpr sm::vec colour1 = { 1.0, 0.0, 0.0 }; constexpr sm::vec colour2 = { 0.0, 0.9, 0.4 }; + std::cout << "creating first...\n" << std::flush; + sm::vec offset = { 0.0, 0.0, 0.0 }; sm::vec start = { 0, 0, 0 }; sm::vec end = { 0.25, 0, 0 }; std::unique_ptr> rvm = std::make_unique> (offset, start, end, 0.1f, colour1, colour1); - v.bindmodel (rvm); + rvm->set_parent (v.get_id()); // A bind model call. howeer, we could pass v.visual_id to the VisualModel constructor rvm->finalize(); + std::cout << "addVisualmodel...\n" << std::flush; v.addVisualModel (rvm); sm::vec start2 = { -0.1, 0.2, 0.6 }; sm::vec end2 = { 0.2, 0.4, 0.6 }; // You can reuse the unique_ptr rvm, once you've transferred ownership with v.addVisualModel (rvm) rvm = std::make_unique>(offset, start2, end2, 0.05f, colour2); - v.bindmodel (rvm); + rvm->set_parent (v.get_id()); rvm->finalize(); + std::cout << "addVisualmodel...\n" << std::flush; v.addVisualModel (rvm); v.keepOpen(); diff --git a/maths b/maths index 9297841f..d856f8c0 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit 9297841f8150d4a587a18b64e1f5dba7b87698ba +Subproject commit d856f8c0c203ed9022679002c82fd9959cfe006b diff --git a/mplot/ColourMap.h b/mplot/ColourMap.h index 0ec2404d..8453cb86 100644 --- a/mplot/ColourMap.h +++ b/mplot/ColourMap.h @@ -9,8 +9,8 @@ #include #include #include -#include +import mplot.tools; import sm.vec; #include import sm.flags; diff --git a/mplot/CoordArrows.h b/mplot/CoordArrows.h index 423de798..9205936c 100644 --- a/mplot/CoordArrows.h +++ b/mplot/CoordArrows.h @@ -21,8 +21,6 @@ module; #include -#include - export module mplot.coordarrows; import mplot.visualtextmodel; @@ -31,6 +29,7 @@ import mplot.visualfont; import mplot.visualcommon; import mplot.colour; import mplot.gl.version; +import mplot.gl.util; import sm.vec; import sm.mat; import sm.flags; diff --git a/mplot/NavMesh.h b/mplot/NavMesh.h index 7299fc93..663b129b 100644 --- a/mplot/NavMesh.h +++ b/mplot/NavMesh.h @@ -20,13 +20,12 @@ #include #include -#include - import sm.vec; import sm.vvec; import sm.flags; import sm.mat; import sm.geometry; +import sm.util; namespace mplot { diff --git a/mplot/RodVisual.h b/mplot/RodVisual.h index 15e3567d..f856f4af 100644 --- a/mplot/RodVisual.h +++ b/mplot/RodVisual.h @@ -50,6 +50,7 @@ namespace mplot //! Initialize vertex buffer objects and vertex array object. void initializeVertices() { + std::cout << "right one called\n"; this->vertexPositions.clear(); this->vertexNormals.clear(); this->vertexColors.clear(); @@ -63,7 +64,7 @@ namespace mplot // Can alternatively use the 'oriented' tube this->computeTube (this->start_coord, this->end_coord, face_uy, face_uz, - this->start_col, this->end_col, this->radius, 6, sm::mathconst::pi_over_6); + this->start_col, this->end_col, this->radius, 60, sm::mathconst::pi_over_6); } } diff --git a/mplot/VisualCommon.h b/mplot/VisualCommon.h index fad501fc..4d48931c 100644 --- a/mplot/VisualCommon.h +++ b/mplot/VisualCommon.h @@ -5,12 +5,12 @@ */ module; +#include #include #include #include #include #include -#include export module mplot.visualcommon; @@ -19,6 +19,7 @@ import sm.range; import sm.vvec; import sm.mat; import mplot.colour; +import mplot.tools; export namespace mplot { diff --git a/mplot/VisualFace.h b/mplot/VisualFace.h index 07107d0d..fe43db11 100644 --- a/mplot/VisualFace.h +++ b/mplot/VisualFace.h @@ -26,8 +26,6 @@ module; #include #include -#include - #include /* @@ -39,6 +37,7 @@ export module mplot.visualface; import mplot.visualcommon; import mplot.visualfont; import mplot.textfeatures; +import mplot.tools; import sm.vec; diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index f91f3b4c..a1cd3a23 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -34,10 +34,7 @@ #include #include -#include - #include -#include import sm.geometry_polyhedra; import sm.quaternion; @@ -47,6 +44,7 @@ import sm.vvec; import sm.range; import sm.algo; import sm.flags; +import sm.base64; // Need to import common here import mplot.visualcommon; @@ -54,8 +52,9 @@ import mplot.visualresources; import mplot.visualtextmodel; import mplot.colour; import mplot.gl.version; +import mplot.gl.util; +import mplot.tools; -#include #include namespace mplot @@ -93,7 +92,7 @@ namespace mplot // Explicitly clear owned VisualTextModels this->texts.clear(); if (this->vbos != nullptr) { - GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->visual_id); + GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->parentVis); if (glfn) { glfn->DeleteBuffers (this->numVBO, this->vbos.get()); glfn->DeleteVertexArrays (1, &this->vao); @@ -104,10 +103,11 @@ namespace mplot //! Common code to call after the vertices have been set up. GL has to have been initialised. void postVertexInit() { - if (this->visual_id == std::numeric_limits::max()) { - throw std::runtime_error ("visual_id is unset"); + std::cout << "postvertexinit...\n" << std::flush; + if (this->parentVis == std::numeric_limits::max()) { + throw std::runtime_error ("parentVis is unset"); } - GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->visual_id); + GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->parentVis); // Do gl memory allocation of vertex array once only if (this->vbos == nullptr) { @@ -184,7 +184,7 @@ namespace mplot } //! Initialize vertex buffer objects and vertex array object. Empty for 'text only' VisualModels. - void initializeVertices() {}; + virtual void initializeVertices() {}; /*! * Helper to make a VisualTextModel and bind it ready for use. * @@ -202,7 +202,7 @@ namespace mplot { // No longer really worth having, as there is only the make_unique call auto tmup = std::make_unique> (tfeatures); - //this->bindmodel (tmup); + tmup->set_parent (this->parentVis); return tmup; } @@ -710,7 +710,7 @@ namespace mplot */ void finalize() { - mplot::VisualResources::i().setContext (this->parentVis); + mplot::VisualResources::i().setContext (this->parentVis); // need context? yes for text. this->initializeVertices(); this->update_bb(); this->flags.set (vm_bools::postVertexInitRequired, true); @@ -1105,9 +1105,6 @@ namespace mplot // A VisualModel may be given a name std::string name = {}; - // The mplot::Visual ID to which I belong. max means unset. - uint32_t visual_id = std::numeric_limits::max(); - //! The current indices index GLuint idx = 0u; GLuint idx_bb = 0u; @@ -1188,10 +1185,7 @@ namespace mplot //! Setter for the parent ID, parentVis void set_parent (const uint32_t _vis) { - if (this->parentVis != std::numeric_limits::max()) { - throw std::runtime_error ("VisualModel: Set the parent pointer once only!"); - } - this->parentVis = _vis; + if (this->parentVis == std::numeric_limits::max()) { this->parentVis = _vis; } } // Flags defaults. @@ -1308,8 +1302,7 @@ namespace mplot //! A model-wide alpha value for the shader float alpha = 1.0f; - // The mplot::VisualBase in which this model exists. (visual_id) - //mplot::VisualBase* parentVis = nullptr; + // The mplot::VisualBase in which this model exists. uint32_t parentVis = std::numeric_limits::max(); //! A vector of pointers to text models that should be rendered. @@ -1320,10 +1313,10 @@ namespace mplot { std::size_t sz = dat.size() * sizeof(float); - if (this->visual_id == std::numeric_limits::max()) { - throw std::runtime_error ("visual_id is unset"); + if (this->parentVis == std::numeric_limits::max()) { + throw std::runtime_error ("parentVis is unset"); } - GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->visual_id); + GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->parentVis); glfn->BindBuffer (GL_ARRAY_BUFFER, buf); mplot::gl::Util::checkError (__FILE__, __LINE__, glfn); glfn->BufferData (GL_ARRAY_BUFFER, sz, dat.data(), GL_STATIC_DRAW); diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index bdbf6b9d..2b70a439 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -29,14 +29,11 @@ module; #include #include -#include #include #include #include -#include - #include #include @@ -58,6 +55,8 @@ import mplot.textgeometry; import mplot.textfeatures; import mplot.coordarrows; import mplot.gl.version; +import mplot.gl.util; +import mplot.tools; import sm.vec; @@ -261,6 +260,7 @@ export namespace mplot unsigned int addVisualModelId (std::unique_ptr& model) { std::unique_ptr> vmp = std::move(model); + std::cout << "set parent on visualmodel to " << visual_id << std::endl; vmp->set_parent (this->visual_id); if (vmp->instanced()) { this->state.set (visual_state::haveInstanced, true); } this->vm.push_back (std::move(vmp)); @@ -276,6 +276,7 @@ export namespace mplot T* addVisualModel (std::unique_ptr& model) { std::unique_ptr> vmp = std::move(model); + std::cout << "set parent on visualmodel to " << visual_id << std::endl; vmp->set_parent (this->visual_id); if (vmp->instanced()) { this->state.set (visual_state::haveInstanced, true); } this->vm.push_back (std::move(vmp)); @@ -1086,6 +1087,8 @@ export namespace mplot return cvm; } + uint32_t get_id() const { return this->visual_id; } + protected: //! Set up a perspective projection based on window width and height. Not public. diff --git a/mplot/VisualResources.h b/mplot/VisualResources.h index a5ea941b..fe4d2613 100644 --- a/mplot/VisualResources.h +++ b/mplot/VisualResources.h @@ -28,7 +28,6 @@ module; #include #include #include -#include #include export module mplot.visualresources; @@ -39,7 +38,7 @@ import mplot.visualfont; import mplot.textfeatures; import mplot.win_t; import mplot.gl.version; - +import mplot.gl.util; import sm.vec; export namespace mplot diff --git a/mplot/VisualTextModel.h b/mplot/VisualTextModel.h index 66e7a461..3913583a 100644 --- a/mplot/VisualTextModel.h +++ b/mplot/VisualTextModel.h @@ -27,7 +27,6 @@ module; #include -#include #include export module mplot.visualtextmodel; @@ -39,6 +38,7 @@ export import mplot.textfeatures; import mplot.visualface; import mplot.colour; import mplot.gl.version; +import mplot.gl.util; import sm.quaternion; import sm.mat; diff --git a/mplot/gl/loadshaders_mx.h b/mplot/gl/loadshaders_mx.h index cd1173af..6d2cef85 100644 --- a/mplot/gl/loadshaders_mx.h +++ b/mplot/gl/loadshaders_mx.h @@ -6,13 +6,14 @@ #include -#include #include #include #include #include #include +import mplot.tools; + namespace mplot::gl { //! Shader loading code. diff --git a/mplot/gl/ssbo_mx.h b/mplot/gl/ssbo_mx.h index 209b688c..262c1dfc 100644 --- a/mplot/gl/ssbo_mx.h +++ b/mplot/gl/ssbo_mx.h @@ -10,11 +10,11 @@ */ #include -#include import sm.vec; import sm.vvec; import sm.range; +import mplot.gl.util; namespace mplot::gl { diff --git a/mplot/gl/util_mx.h b/mplot/gl/util_mx.h index 54c41aa9..ba4571b6 100644 --- a/mplot/gl/util_mx.h +++ b/mplot/gl/util_mx.h @@ -1,16 +1,23 @@ -#pragma once - /* * Common code for GL functionality in mathplot programs that use multicontext GLAD headers. * * Author: Seb James. */ +module; + +#if defined __gl3_h_ || defined __gl_h_ +// GL headers have been externally included +#else +# include +#endif #include #include #include -namespace mplot::gl::Util +export module mplot.gl.util; + +export namespace mplot::gl::Util { GLenum checkError (const char *file, int line, GladGLContext* glfn) { diff --git a/mplot/tools.h b/mplot/tools.h index 11a95e2c..25dde353 100644 --- a/mplot/tools.h +++ b/mplot/tools.h @@ -3,7 +3,7 @@ * * \author Seb James */ -#pragma once +module; #include #include @@ -33,30 +33,32 @@ #define CHARS_NUMERIC_ALPHALOWER "etaoinshrdlcumwfgypbvkjxqz0123456789" #define CHARS_NUMERIC_ALPHAUPPER "0123456789ETAOINSHRDLCUMWFGYPBVKJXQZ" -namespace mplot +export module mplot.tools; + +export namespace mplot { /*! * Chars which are safe for IP domainnames. Allow numeric and alpha chars, the underscore and the * hyphen. colon is strictly allowed, but best avoided. */ - static constexpr std::string_view chars_xml_safe {CHARS_NUMERIC_ALPHA"_-"}; + constexpr std::string_view chars_xml_safe {CHARS_NUMERIC_ALPHA"_-"}; /*! * These are the chars which are acceptable for use in both unix, mac AND windows file * names. This doesn't guarantee a safe Windows filename, as Windows imposes some extra * conditions (no '.' at end of name, some files such as NUL.txt AUX.txt disallowed). */ - static constexpr std::string_view chars_common_file_safe {CHARS_NUMERIC_ALPHA"_-.{}^[]`=,;"}; + constexpr std::string_view chars_common_file_safe {CHARS_NUMERIC_ALPHA"_-.{}^[]`=,;"}; /*! * Chars which are safe for IP domainnames */ - static constexpr std::string_view chars_ip_domainname_safe {CHARS_NUMERIC_ALPHA"-."}; + constexpr std::string_view chars_ip_domainname_safe {CHARS_NUMERIC_ALPHA"-."}; /*! * Chars which are safe for IP addresses */ - static constexpr std::string_view chars_ip_address_safe {CHARS_NUMERIC"."}; + constexpr std::string_view chars_ip_address_safe {CHARS_NUMERIC"."}; //! Allows use of transform and tolower() on strings with GNU compiler struct to_lower { char operator() (const char c) const { return tolower(c); } }; From cbad5a1fa1e1c1fe63d0f0e6e8dd5b88a5be11d4 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 6 Mar 2026 19:22:40 +0000 Subject: [PATCH 024/106] Prefer static linking of glad --- mplot/glad/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mplot/glad/CMakeLists.txt b/mplot/glad/CMakeLists.txt index 8e03817f..7966b48b 100644 --- a/mplot/glad/CMakeLists.txt +++ b/mplot/glad/CMakeLists.txt @@ -2,4 +2,4 @@ install(FILES gl.h gl_mx.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include/mplot/gla # Build glad library here include_directories(BEFORE ${PROJECT_SOURCE_DIR}) -add_library(glad SHARED gl.c) +add_library(glad STATIC gl.c) From f8e2e4080ed673f0d653c442b7e55fb286b81aef Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 6 Mar 2026 19:27:47 +0000 Subject: [PATCH 025/106] Forgotten files --- examples/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a50c58b6..b5950227 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -65,6 +65,7 @@ target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/maths/sm/flags ${PROJECT_SOURCE_DIR}/maths/sm/algo From 73c75181c09bcac3c46c84125c57225b806bf874 Mon Sep 17 00:00:00 2001 From: Seb James Date: Sun, 8 Mar 2026 16:44:31 +0000 Subject: [PATCH 026/106] grid_simple now works. VisualModel, VisualDataModel modularized. --- examples/CMakeLists.txt | 44 +++++++++++++++++++++++++++++++++++----- examples/grid_simple.cpp | 24 ++++++++++++++-------- examples/rod.cpp | 3 +-- maths | 2 +- mplot/ColourMap.h | 11 ++++++---- mplot/GridVisual.h | 7 ++++--- mplot/NavMesh.h | 10 ++++++--- mplot/RodVisual.h | 2 +- mplot/VisualDataModel.h | 12 ++++++----- mplot/VisualModel.h | 10 +++++---- mplot/VisualOwnable.h | 6 ++++-- 11 files changed, 93 insertions(+), 38 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index b5950227..265a3614 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -27,6 +27,7 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/maths/sm/centroid ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 + ${PROJECT_SOURCE_DIR}/maths/sm/crc32 ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h ${PROJECT_SOURCE_DIR}/mplot/Visual.h ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h @@ -37,6 +38,10 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.h + ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h ${PROJECT_SOURCE_DIR}/mplot/win_t.h ${PROJECT_SOURCE_DIR}/mplot/colour.h @@ -65,6 +70,8 @@ target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h + ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/maths/sm/flags @@ -98,8 +105,12 @@ target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h + ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 + ${PROJECT_SOURCE_DIR}/maths/sm/crc32 ${PROJECT_SOURCE_DIR}/maths/sm/flags ${PROJECT_SOURCE_DIR}/maths/sm/algo ${PROJECT_SOURCE_DIR}/maths/sm/range @@ -116,21 +127,44 @@ target_link_libraries(rod OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata add_executable(grid_simple grid_simple.cpp) target_sources(grid_simple PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES + ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/gl/version.h + ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h + ${PROJECT_SOURCE_DIR}/mplot/colour.h + ${PROJECT_SOURCE_DIR}/mplot/win_t.h + ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h + ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h + ${PROJECT_SOURCE_DIR}/mplot/Visual.h + ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h + ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h + ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h + ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h + ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h + ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.h + ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/maths/sm/util + ${PROJECT_SOURCE_DIR}/maths/sm/base64 + ${PROJECT_SOURCE_DIR}/maths/sm/crc32 ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/scale + ${PROJECT_SOURCE_DIR}/maths/sm/algo ${PROJECT_SOURCE_DIR}/maths/sm/range ${PROJECT_SOURCE_DIR}/maths/sm/random ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/vvec - ${PROJECT_SOURCE_DIR}/maths/sm/centroid ${PROJECT_SOURCE_DIR}/maths/sm/quaternion ${PROJECT_SOURCE_DIR}/maths/sm/mat ${PROJECT_SOURCE_DIR}/maths/sm/geometry ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/vvec + ${PROJECT_SOURCE_DIR}/maths/sm/scale + ${PROJECT_SOURCE_DIR}/maths/sm/centroid ${PROJECT_SOURCE_DIR}/maths/sm/grid ) -target_link_libraries(grid_simple OpenGL::GL glfw Freetype::Freetype) +target_link_libraries(grid_simple OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) # # Any example that uses sm::hexgrid or sm::cartgrid requires diff --git a/examples/grid_simple.cpp b/examples/grid_simple.cpp index f730e44a..6a1ddfd4 100644 --- a/examples/grid_simple.cpp +++ b/examples/grid_simple.cpp @@ -5,12 +5,16 @@ #include #include #include +#include import sm.vec; import sm.grid; -#include -#include // import mplot.core; +import mplot.visual; +import mplot.gl.version; +import mplot.visualmodel; +import mplot.textfeatures; + #include // import mplot.gridvisual; int main() @@ -46,7 +50,9 @@ int main() sm::vec offset = { -step * grid.width(), -step * grid.width(), 0.0f }; auto gv = std::make_unique>(&grid, offset); - v.bindmodel (gv); + // v.bindmodel (gv); becomes... + gv->set_parent (v.get_id()); + gv->gridVisMode = mplot::GridVisMode::Triangles; gv->setScalarData (&data); gv->cm.setType (mplot::ColourMapType::Cork); @@ -56,7 +62,8 @@ int main() offset = { step * grid.width(), -step * grid.width(), 0.0f }; gv = std::make_unique>(&grid, offset); - v.bindmodel (gv); + //v.bindmodel (gv); + gv->set_parent (v.get_id()); gv->gridVisMode = mplot::GridVisMode::RectInterp; gv->setScalarData (&data); @@ -74,7 +81,8 @@ int main() offset = { -step * grid.width(), step * grid.width(), 0.0f }; gv = std::make_unique>(&grid, offset); - v.bindmodel (gv); + //v.bindmodel (gv); + gv->set_parent (v.get_id()); gv->gridVisMode = mplot::GridVisMode::Columns; gv->interpolate_colour_sides (true); gv->setScalarData (&data); @@ -85,7 +93,7 @@ int main() offset = { step * grid.width(), step * grid.width(), 0.0f }; gv = std::make_unique>(&grid, offset); - v.bindmodel (gv); + gv->set_parent (v.get_id()); gv->gridVisMode = mplot::GridVisMode::Columns; //gv->interpolate_colour_sides = false; // default //gv->clr_east_column = mplot::colour::black; // These are defaults but you can change them @@ -98,7 +106,7 @@ int main() offset = { 3 * step * grid.width(), step * grid.width(), 0.0f }; gv = std::make_unique>(&grid, offset); - v.bindmodel (gv); + gv->set_parent (v.get_id()); gv->gridVisMode = mplot::GridVisMode::Pixels; gv->setScalarData (&data); gv->cm.setType (mplot::ColourMapType::Navia); @@ -108,7 +116,7 @@ int main() offset = { 3 * step * grid.width(), -step * grid.width(), 0.0f }; gv = std::make_unique>(&grid, offset); - v.bindmodel (gv); + gv->set_parent (v.get_id()); gv->gridVisMode = mplot::GridVisMode::RectInterp; gv->setScalarData (&data); gv->cm.setType (mplot::ColourMapType::Navia); diff --git a/examples/rod.cpp b/examples/rod.cpp index 7e9ecfc6..c8a59d36 100644 --- a/examples/rod.cpp +++ b/examples/rod.cpp @@ -6,8 +6,7 @@ import mplot.visual; import mplot.gl.version; - -#include +import mplot.colourmap; #include // import mplot.gridvisual; diff --git a/maths b/maths index d856f8c0..c2f7bf5f 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit d856f8c0c203ed9022679002c82fd9959cfe006b +Subproject commit c2f7bf5f1fa087621d6fdedea98c0da59a1c397f diff --git a/mplot/ColourMap.h b/mplot/ColourMap.h index 8453cb86..c4a07634 100644 --- a/mplot/ColourMap.h +++ b/mplot/ColourMap.h @@ -1,4 +1,4 @@ -#pragma once +module; #include // Colour map tables from matplotlib #include // Colour map tables from Fabio Crameri @@ -10,13 +10,16 @@ #include #include +#include + +export module mplot.colourmap; + import mplot.tools; import sm.vec; -#include import sm.flags; -#include +import sm.crc32; -namespace mplot +export namespace mplot { //! Different colour maps types. enum class ColourMapType : uint32_t diff --git a/mplot/GridVisual.h b/mplot/GridVisual.h index fc04dfe3..a6de7dd3 100644 --- a/mplot/GridVisual.h +++ b/mplot/GridVisual.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -8,9 +9,9 @@ import sm.grid; import sm.vec; import sm.flags; - -#include -#include +import mplot.colourmap; +import mplot.colour; +import mplot.visualdatamodel; namespace mplot { diff --git a/mplot/NavMesh.h b/mplot/NavMesh.h index 663b129b..4a9fe28d 100644 --- a/mplot/NavMesh.h +++ b/mplot/NavMesh.h @@ -7,19 +7,23 @@ * \author Seb James * \date October 2025 */ - -#pragma once +module; #include +#include +#include #include #include #include #include #include #include +#include #include #include +export module mplot.visualmodel:navmesh; + import sm.vec; import sm.vvec; import sm.flags; @@ -27,7 +31,7 @@ import sm.mat; import sm.geometry; import sm.util; -namespace mplot +export namespace mplot { namespace mesh { diff --git a/mplot/RodVisual.h b/mplot/RodVisual.h index f856f4af..15aec9f5 100644 --- a/mplot/RodVisual.h +++ b/mplot/RodVisual.h @@ -2,9 +2,9 @@ #include #include -#include import sm.vec; +import mplot.visualmodel; namespace mplot { diff --git a/mplot/VisualDataModel.h b/mplot/VisualDataModel.h index 34754598..5e9a63b5 100644 --- a/mplot/VisualDataModel.h +++ b/mplot/VisualDataModel.h @@ -1,21 +1,23 @@ /*! * VisualModels which have data. */ -#pragma once +module; #include #include +export module mplot.visualdatamodel; + import sm.vec; import sm.vvec; import sm.scale; import sm.centroid; -#include -#include - +export import mplot.visualmodel; +import mplot.colourmap; +import mplot.gl.version; -namespace mplot +export namespace mplot { //! VisualDataModel implementation base class containing common functionality - all the //! sm::scale objects and methods. diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index a1cd3a23..04327512 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -9,8 +9,7 @@ * \author Seb James * \date March 2025 */ - -#pragma once +module; #if defined __gl3_h_ || defined __gl_h_ // GL headers have been externally included @@ -36,6 +35,8 @@ #include +export module mplot.visualmodel; + import sm.geometry_polyhedra; import sm.quaternion; import sm.mat; @@ -55,9 +56,10 @@ import mplot.gl.version; import mplot.gl.util; import mplot.tools; -#include +import :navmesh; +//#include -namespace mplot +export namespace mplot { union float_bytes // for gltf output { diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index 2b70a439..385e33ea 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -36,8 +36,6 @@ module; #include -#include - // Use Lode Vandevenne's PNG encoder #define LODEPNG_NO_COMPILE_DECODER 1 #define LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS 1 @@ -47,6 +45,7 @@ module; export module mplot.visualownable; +import mplot.visualmodel; import mplot.win_t; import mplot.visualcommon; import mplot.visualresources; @@ -59,6 +58,9 @@ import mplot.gl.util; import mplot.tools; import sm.vec; +import sm.flags; +import sm.quaternion; +import sm.mat; export namespace mplot { From 891e12ea4d44e2b349215858b75aa5451e01ec93 Mon Sep 17 00:00:00 2001 From: Seb James Date: Sun, 8 Mar 2026 16:59:29 +0000 Subject: [PATCH 027/106] graph1 now compiles --- examples/CMakeLists.txt | 77 ++++++++++++++++++++++++++++++++++++----- examples/graph1.cpp | 6 ++-- examples/showcase.cpp | 4 +-- mplot/DatasetStyle.h | 5 +-- mplot/GraphVisual.h | 16 +++++---- mplot/HexGridVisual.h | 9 ++--- 6 files changed, 90 insertions(+), 27 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 265a3614..e31320a4 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -123,6 +123,46 @@ target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/maths/sm/vvec) target_link_libraries(rod OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) +add_executable(graph1 graph1.cpp) +target_sources(graph1 PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES + ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/gl/version.h + ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h + ${PROJECT_SOURCE_DIR}/mplot/colour.h + ${PROJECT_SOURCE_DIR}/mplot/win_t.h + ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h + ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h + ${PROJECT_SOURCE_DIR}/mplot/Visual.h + ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h + ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h + ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h + ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h + ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h + ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h + ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/maths/sm/util + ${PROJECT_SOURCE_DIR}/maths/sm/base64 + ${PROJECT_SOURCE_DIR}/maths/sm/crc32 + ${PROJECT_SOURCE_DIR}/maths/sm/flags + ${PROJECT_SOURCE_DIR}/maths/sm/algo + ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/random + ${PROJECT_SOURCE_DIR}/maths/sm/vec + ${PROJECT_SOURCE_DIR}/maths/sm/scale + ${PROJECT_SOURCE_DIR}/maths/sm/histo + ${PROJECT_SOURCE_DIR}/maths/sm/grid + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/geometry + ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/vvec) +target_link_libraries(graph1 OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) + # mplot::Grid is runtime-configured add_executable(grid_simple grid_simple.cpp) target_sources(grid_simple PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} @@ -174,25 +214,44 @@ if(ARMADILLO_FOUND) add_executable(showcase showcase.cpp) target_sources(showcase PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES + ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/gl/version.h + ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h + ${PROJECT_SOURCE_DIR}/mplot/colour.h + ${PROJECT_SOURCE_DIR}/mplot/win_t.h + ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h + ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h + ${PROJECT_SOURCE_DIR}/mplot/Visual.h + ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h + ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h + ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h + ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h + ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h + ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.h + ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/maths/sm/util + ${PROJECT_SOURCE_DIR}/maths/sm/base64 + ${PROJECT_SOURCE_DIR}/maths/sm/crc32 ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/scale + ${PROJECT_SOURCE_DIR}/maths/sm/algo ${PROJECT_SOURCE_DIR}/maths/sm/range ${PROJECT_SOURCE_DIR}/maths/sm/random ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/vvec - ${PROJECT_SOURCE_DIR}/maths/sm/centroid ${PROJECT_SOURCE_DIR}/maths/sm/quaternion ${PROJECT_SOURCE_DIR}/maths/sm/mat ${PROJECT_SOURCE_DIR}/maths/sm/geometry ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/vvec + ${PROJECT_SOURCE_DIR}/maths/sm/scale + ${PROJECT_SOURCE_DIR}/maths/sm/centroid ${PROJECT_SOURCE_DIR}/maths/sm/grid - ${PROJECT_SOURCE_DIR}/maths/sm/histo - ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex - ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord - ${PROJECT_SOURCE_DIR}/maths/sm/hex ) - target_link_libraries(showcase OpenGL::GL glfw Freetype::Freetype) + target_link_libraries(showcase OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) endif(ARMADILLO_FOUND) if(0) # During development diff --git a/examples/graph1.cpp b/examples/graph1.cpp index eafda6ce..d835e3bf 100644 --- a/examples/graph1.cpp +++ b/examples/graph1.cpp @@ -1,7 +1,7 @@ // Visualize a graph. Minimal example showing how a default graph appears -#include +import mplot.visual; #include -#include +import sm.vvec; int main() { @@ -10,7 +10,7 @@ int main() // Create a GraphVisual object (obtaining a unique_ptr to the object) with a spatial offset within the scene of 0,0,0 auto gv = std::make_unique> (sm::vec({0,0,0})); // This mandatory line of boilerplate code sets the parent pointer in GraphVisual and binds some functions - v.bindmodel (gv); + gv->set_parent (v.get_id()); // Data for the x axis. A vvec is like std::vector, but with built-in maths methods sm::vvec x; // This works like numpy's linspace() (the 3 args are "start", "end" and "num"): diff --git a/examples/showcase.cpp b/examples/showcase.cpp index 28aafa98..50f965cf 100644 --- a/examples/showcase.cpp +++ b/examples/showcase.cpp @@ -7,7 +7,7 @@ import sm.grid; #include #include -#include +import mplot.visual; #include #include #include @@ -371,5 +371,3 @@ int main() return 0; } - - diff --git a/mplot/DatasetStyle.h b/mplot/DatasetStyle.h index aef5eb8d..00cb31ba 100644 --- a/mplot/DatasetStyle.h +++ b/mplot/DatasetStyle.h @@ -5,8 +5,9 @@ import sm.vec; import sm.flags; #include -#include -#include + +import mplot.colourmap; +import mplot.colour; namespace mplot { diff --git a/mplot/GraphVisual.h b/mplot/GraphVisual.h index de945423..ba51d97c 100644 --- a/mplot/GraphVisual.h +++ b/mplot/GraphVisual.h @@ -9,12 +9,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include import sm.scale; import sm.range; @@ -24,15 +26,17 @@ import sm.quaternion; import sm.histo; import sm.grid; -#include -#include -#include -#include #include #include -#include #include -#include + +import mplot.tools; +import mplot.colour; +import mplot.gl.version; +import mplot.visualmodel; +import mplot.colourmap; +import mplot.visualtextmodel; +import mplot.visualfont; namespace mplot { diff --git a/mplot/HexGridVisual.h b/mplot/HexGridVisual.h index 7be96a74..8d7270aa 100644 --- a/mplot/HexGridVisual.h +++ b/mplot/HexGridVisual.h @@ -7,10 +7,11 @@ import sm.vec; import sm.vvec; #include import sm.scale; -#include -#include -#include -#include + +import mplot.gl.version; +import mplot.tools; +import mplot.visualdatamodel; +import mplot.colourmap; /* * Macros for testing neighbours. The step along for neighbours on the From e1ba0f38acd0966992188774f4061a3e23dd4e3a Mon Sep 17 00:00:00 2001 From: Seb James Date: Sun, 8 Mar 2026 17:13:47 +0000 Subject: [PATCH 028/106] modularize GraphVisual --- examples/CMakeLists.txt | 9 +++++++++ examples/graph1.cpp | 4 ++-- mplot/DatasetStyle.h | 10 +++++++--- mplot/GraphVisual.h | 19 ++++++++++++------- mplot/graphing.h | 16 +++++++++------- mplot/graphstyles.h | 4 ++-- 6 files changed, 41 insertions(+), 21 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index e31320a4..5ce4bdee 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -48,6 +48,11 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/tools.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h + + ${PROJECT_SOURCE_DIR}/mplot/graphing.h + ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h + ${PROJECT_SOURCE_DIR}/mplot/DatasetStyle.h + ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h PROPERTIES LANGUAGE CXX ) @@ -145,6 +150,10 @@ target_sources(graph1 PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/mplot/graphing.h + ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h + ${PROJECT_SOURCE_DIR}/mplot/DatasetStyle.h + ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/maths/sm/crc32 diff --git a/examples/graph1.cpp b/examples/graph1.cpp index d835e3bf..de11fd42 100644 --- a/examples/graph1.cpp +++ b/examples/graph1.cpp @@ -1,7 +1,7 @@ // Visualize a graph. Minimal example showing how a default graph appears +#include import mplot.visual; -#include -import sm.vvec; +import mplot.graphvisual; // exports sm.vvec and sm.vec int main() { diff --git a/mplot/DatasetStyle.h b/mplot/DatasetStyle.h index 00cb31ba..1013cfdf 100644 --- a/mplot/DatasetStyle.h +++ b/mplot/DatasetStyle.h @@ -1,15 +1,19 @@ -#pragma once +module; #include #include + +export module mplot.datasetstyle; + import sm.vec; import sm.flags; -#include + +export import mplot.graphstyles; import mplot.colourmap; import mplot.colour; -namespace mplot +export namespace mplot { // Boolean flags relating to quiver plots that form part of a DatasetStyle enum class quiver_flags : unsigned int diff --git a/mplot/GraphVisual.h b/mplot/GraphVisual.h index ba51d97c..6a0f84f1 100644 --- a/mplot/GraphVisual.h +++ b/mplot/GraphVisual.h @@ -4,7 +4,7 @@ * \author Seb James * \date 2020 */ -#pragma once +module; #include #include @@ -15,20 +15,25 @@ #include #include #include +#include #include #include + +export module mplot.graphvisual; + +import mplot.graphing; +export import mplot.graphstyles; +export import mplot.datasetstyle; + import sm.scale; import sm.range; -import sm.vec; -import sm.vvec; +export import sm.vec; +export import sm.vvec; import sm.quaternion; import sm.histo; import sm.grid; -#include -#include -#include import mplot.tools; import mplot.colour; @@ -38,7 +43,7 @@ import mplot.colourmap; import mplot.visualtextmodel; import mplot.visualfont; -namespace mplot +export namespace mplot { /*! * A VisualModel for showing a 2D graph. diff --git a/mplot/graphing.h b/mplot/graphing.h index a595de2f..ba5d2ba0 100644 --- a/mplot/graphing.h +++ b/mplot/graphing.h @@ -5,8 +5,7 @@ * Seb James * March 2025 */ - -#pragma once +module; #include #include @@ -22,16 +21,19 @@ #endif #include + +export module mplot.graphing; + import sm.range; import sm.algo; import sm.vvec; -namespace mplot::graphing +export namespace mplot::graphing { //! Graph-specific number formatting for tick labels. You must pass in an adjacent //! label (which affects the optimum precision to use for formatting) template - static std::string number_format (const F num, const F adjacent_num) + std::string number_format (const F num, const F adjacent_num) { sm::range num_sigcols = sm::algo::significant_cols (num); F num_diff = std::abs (num - adjacent_num); @@ -99,7 +101,7 @@ namespace mplot::graphing * of maketicks. */ template - static std::deque maketicks (F rmin, F rmax, float realmin, float realmax, const sm::range& _num_ticks_range) + std::deque maketicks (F rmin, F rmax, float realmin, float realmax, const sm::range& _num_ticks_range) { std::deque ticks = {}; @@ -193,7 +195,7 @@ namespace mplot::graphing * This overload accepts separate min and max for the preferred number of ticks. */ template - static std::deque maketicks (F rmin, F rmax, float realmin, float realmax, const F _min_num_ticks = 3, const F _max_num_ticks = 10) + std::deque maketicks (F rmin, F rmax, float realmin, float realmax, const F _min_num_ticks = 3, const F _max_num_ticks = 10) { sm::range _num_ticks_range(_min_num_ticks, _max_num_ticks); return mplot::graphing::maketicks (rmin, rmax, realmin, realmax, _num_ticks_range); @@ -203,7 +205,7 @@ namespace mplot::graphing * Make ticks overload for a specified number of ticks */ template - static std::deque maketicks (F rmin, F rmax, float realmin, float realmax, const F num_ticks) + std::deque maketicks (F rmin, F rmax, float realmin, float realmax, const F num_ticks) { sm::range _num_ticks_range(num_ticks, num_ticks); return mplot::graphing::maketicks (rmin, rmax, realmin, realmax, _num_ticks_range); diff --git a/mplot/graphstyles.h b/mplot/graphstyles.h index 9fa131ae..01b7da56 100644 --- a/mplot/graphstyles.h +++ b/mplot/graphstyles.h @@ -2,9 +2,9 @@ * Graphing styles - a number of enumerated classes. */ -#pragma once +export module mplot.graphstyles; -namespace mplot +export namespace mplot { //! What shape for the graph markers? enum class markerstyle From 0d0461bee3fc81251e93fa4606f2fdacf91dc037 Mon Sep 17 00:00:00 2001 From: Seb James Date: Sun, 8 Mar 2026 17:17:46 +0000 Subject: [PATCH 029/106] Preemptive update of readme --- README.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 83b454dc..8c3254f7 100644 --- a/README.md +++ b/README.md @@ -36,14 +36,14 @@ This quick start shows dependency installation for Linux, because on this platfo sudo apt install build-essential cmake git wget \ nlohmann-json3-dev librapidxml-dev \ freeglut3-dev libglu1-mesa-dev libxmu-dev libxi-dev \ - libglfw3-dev libfreetype-dev libarmadillo-dev libhdf5-dev + libglfw3-dev libfreetype-dev libarmadillo-dev libhdf5-dev clang-23 # yes, it's bleeding edge, no this won't work git clone --recurse-submodules git@github.com:sebsjames/mathplot # Get your copy of the morphologica code cd mathplot mkdir build # Create a build directory cd build -cmake .. # Call cmake to generate the makefiles -make graph1 # Compile a single one of the examples. Add VERBOSE=1 to see the compiler commands. +cmake .. -GNinja # Call cmake to generate the makefiles +ninja graph1 # Compile a single one of the examples. Add VERBOSE=1 to see the compiler commands. ./examples/graph1 # Run the program. You should see a graph of a cubic function. # After closing the graph1 program, open its source code and modify something (see examples/graph2.cpp for ideas) gedit ../examples/graph1.cpp @@ -51,19 +51,19 @@ gedit ../examples/graph1.cpp The program graph1.cpp is: ```c++ // Visualize a graph. Minimal example showing how a default graph appears -#include // vvec is part of Seb's maths library -#include -#include +#include +import mplot.visual; +import mplot.graphvisual; // exports sm.vvec and sm.vec int main() { - // Set up your mplot::Visual 'scene environment'. + // Set up a mplot::Visual 'scene environment'. mplot::Visual v(1024, 768, "Made with mplot::GraphVisual"); - // Create a new GraphVisual object with offset within the scene of 0,0,0 + // Create a GraphVisual object (obtaining a unique_ptr to the object) with a spatial offset within the scene of 0,0,0 auto gv = std::make_unique> (sm::vec({0,0,0})); - // Boilerplate bindmodel function call - do this for every model you add to a Visual - v.bindmodel (gv); - // Data for the x axis. sm::vvec is like std::vector, but with built-in maths methods + // This mandatory line of boilerplate code sets the parent pointer in GraphVisual and binds some functions + gv->set_parent (v.get_id()); + // Data for the x axis. A vvec is like std::vector, but with built-in maths methods sm::vvec x; // This works like numpy's linspace() (the 3 args are "start", "end" and "num"): x.linspace (-0.5, 0.8, 14); @@ -71,10 +71,12 @@ int main() gv->setdata (x, x.pow(3)); // finalize() makes the GraphVisual compute the vertices of the OpenGL model gv->finalize(); - // Add the GraphVisual OpenGL model to the Visual scene (which takes ownership of the unique_ptr) + // Add the GraphVisual OpenGL model to the Visual scene, transferring ownership of the unique_ptr v.addVisualModel (gv); // Render the scene on the screen until user quits with 'Ctrl-q' v.keepOpen(); + // Because v owns the unique_ptr to the GraphVisual, its memory will be deallocated when v goes out of scope. + return 0; } ``` The program generates a clean looking graph... From 4338b7386ddebf1a2659b75dcd771abeb463a9e2 Mon Sep 17 00:00:00 2001 From: Seb James Date: Sun, 8 Mar 2026 18:10:11 +0000 Subject: [PATCH 030/106] Breadcrumbs example works --- examples/CMakeLists.txt | 48 ++++++++++++++++++++++++++++++++++ examples/breadcrumbs.cpp | 19 ++++++++------ mplot/GeodesicVisual.h | 5 ++-- mplot/InstancedScatterVisual.h | 9 ++++--- 4 files changed, 68 insertions(+), 13 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 5ce4bdee..d2b91d9c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -215,6 +215,54 @@ target_sources(grid_simple PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURC ) target_link_libraries(grid_simple OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) +# This sphere example uses constexpr code +if(NOT APPLE) + # Instancing also not available on Apple (limited to OpenGL 4.1) + #add_executable(scatter_instanced scatter_instanced.cpp) + #target_link_libraries(scatter_instanced OpenGL::GL glfw Freetype::Freetype) + add_executable(breadcrumbs breadcrumbs.cpp) + target_sources(breadcrumbs PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES + ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/gl/version.h + ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h + ${PROJECT_SOURCE_DIR}/mplot/colour.h + ${PROJECT_SOURCE_DIR}/mplot/win_t.h + ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h + ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h + ${PROJECT_SOURCE_DIR}/mplot/Visual.h + ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h + ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h + ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h + ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h + ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h + ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h + ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h + ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/maths/sm/util + ${PROJECT_SOURCE_DIR}/maths/sm/base64 + ${PROJECT_SOURCE_DIR}/maths/sm/crc32 + ${PROJECT_SOURCE_DIR}/maths/sm/flags + ${PROJECT_SOURCE_DIR}/maths/sm/algo + ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/random + ${PROJECT_SOURCE_DIR}/maths/sm/vec + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/geometry + ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/vvec + ${PROJECT_SOURCE_DIR}/maths/sm/scale + ${PROJECT_SOURCE_DIR}/maths/sm/centroid + ${PROJECT_SOURCE_DIR}/maths/sm/grid + ) + target_link_libraries(breadcrumbs OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) +endif() + # # Any example that uses sm::hexgrid or sm::cartgrid requires # libarmadillo (because the classes use sm::BezCurve). diff --git a/examples/breadcrumbs.cpp b/examples/breadcrumbs.cpp index a19d0634..3842525a 100644 --- a/examples/breadcrumbs.cpp +++ b/examples/breadcrumbs.cpp @@ -1,17 +1,20 @@ /* * Visualize a test surface */ +#include #include #include #include #include -#include -#include -#include +#include +import sm.scale; +import sm.vec; +import sm.vvec; + +import mplot.visual; +import mplot.colourmap; -#include -#include #include #include @@ -41,7 +44,7 @@ int main() // A normal, non instanced model. A sphere to orbit around. auto gv1 = std::make_unique> (sm::vec<>{}, 0.2f); gv1->name = "geodesic"; - v.bindmodel (gv1); + gv1->set_parent (v.get_id()); gv1->iterations = 3; gv1->cm.setType (mplot::ColourMapType::Tofino); gv1->finalize(); @@ -66,7 +69,7 @@ int main() auto isv = std::make_unique> (sm::vec<>{}); isv->name = "isv1"; - v.bindmodel (isv); + isv->set_parent (v.get_id()); isv->max_instances = dsz; isv->radiusFixed = 0.03f; isv->finalize(); @@ -75,7 +78,7 @@ int main() // Another one isv = std::make_unique> (sm::vec<>{0,0.1,0}); isv->name = "isv2"; - v.bindmodel (isv); + isv->set_parent (v.get_id()); isv->max_instances = dsz; isv->radiusFixed = 0.03f; isv->finalize(); diff --git a/mplot/GeodesicVisual.h b/mplot/GeodesicVisual.h index cc9704bf..4d810304 100644 --- a/mplot/GeodesicVisual.h +++ b/mplot/GeodesicVisual.h @@ -5,8 +5,9 @@ import sm.vec; import sm.vvec; import sm.scale; import sm.geometry; -#include -#include +import sm.geometry_polyhedra; +import mplot.visualmodel; +import mplot.colourmap; namespace mplot { diff --git a/mplot/InstancedScatterVisual.h b/mplot/InstancedScatterVisual.h index 2cdd6680..3595a3e5 100644 --- a/mplot/InstancedScatterVisual.h +++ b/mplot/InstancedScatterVisual.h @@ -10,9 +10,12 @@ #include #include import sm.vec; -#include -#include -#include + +import mplot.gl.version; +import mplot.tools; +import mplot.visualmodel; +import mplot.graphstyles; +import mplot.colour; namespace mplot { From ea9609fa81f610c1bcd0b548b44630c093efe0ad Mon Sep 17 00:00:00 2001 From: Seb James Date: Sun, 8 Mar 2026 20:58:42 +0000 Subject: [PATCH 031/106] modularize GridVisual --- examples/CMakeLists.txt | 11 +++++++++++ examples/grid_simple.cpp | 4 ++-- mplot/GridVisual.h | 10 +++++++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index d2b91d9c..9c15a392 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -53,6 +53,9 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h ${PROJECT_SOURCE_DIR}/mplot/DatasetStyle.h ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h + + ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h + PROPERTIES LANGUAGE CXX ) @@ -196,6 +199,7 @@ target_sources(grid_simple PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURC ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.h ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/maths/sm/crc32 @@ -290,6 +294,13 @@ if(ARMADILLO_FOUND) ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.h ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + + ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h + ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h + ${PROJECT_SOURCE_DIR}/mplot/graphing.h + ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h + ${PROJECT_SOURCE_DIR}/mplot/DatasetStyle.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 diff --git a/examples/grid_simple.cpp b/examples/grid_simple.cpp index 6a1ddfd4..13a7f204 100644 --- a/examples/grid_simple.cpp +++ b/examples/grid_simple.cpp @@ -14,8 +14,8 @@ import mplot.visual; import mplot.gl.version; import mplot.visualmodel; import mplot.textfeatures; - -#include // import mplot.gridvisual; +import mplot.gridvisual; +import mplot.colourmap; int main() { diff --git a/mplot/GridVisual.h b/mplot/GridVisual.h index a6de7dd3..11e63f9e 100644 --- a/mplot/GridVisual.h +++ b/mplot/GridVisual.h @@ -1,4 +1,4 @@ -#pragma once +module; #include #include @@ -6,14 +6,18 @@ #include #include +export module mplot.gridvisual; + import sm.grid; -import sm.vec; +export import sm.vec; import sm.flags; + +import mplot.gl.version; import mplot.colourmap; import mplot.colour; import mplot.visualdatamodel; -namespace mplot +export namespace mplot { /*! * How to visualize a grid. You could draw a triangle map with vertices at the centres of the From 2b582bb16a428220bc7ddbb88f83ff5c1e8cf62c Mon Sep 17 00:00:00 2001 From: Seb James Date: Sun, 8 Mar 2026 21:02:32 +0000 Subject: [PATCH 032/106] Modularlized RodVisual --- examples/CMakeLists.txt | 3 +++ examples/rod.cpp | 7 +++---- mplot/GridVisual.h | 3 ++- mplot/RodVisual.h | 10 +++++++--- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 9c15a392..e639215c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -56,6 +56,8 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h + ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h + PROPERTIES LANGUAGE CXX ) @@ -115,6 +117,7 @@ target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 diff --git a/examples/rod.cpp b/examples/rod.cpp index c8a59d36..ad17ccca 100644 --- a/examples/rod.cpp +++ b/examples/rod.cpp @@ -4,13 +4,12 @@ #include #include +import sm.vec; + import mplot.visual; import mplot.gl.version; import mplot.colourmap; - -#include // import mplot.gridvisual; - -import sm.vec; +import mplot.rodvisual; int main() { diff --git a/mplot/GridVisual.h b/mplot/GridVisual.h index 11e63f9e..20bdff53 100644 --- a/mplot/GridVisual.h +++ b/mplot/GridVisual.h @@ -15,7 +15,8 @@ import sm.flags; import mplot.gl.version; import mplot.colourmap; import mplot.colour; -import mplot.visualdatamodel; +export import mplot.visualmodel; +export import mplot.visualdatamodel; export namespace mplot { diff --git a/mplot/RodVisual.h b/mplot/RodVisual.h index 15aec9f5..8dc3bb70 100644 --- a/mplot/RodVisual.h +++ b/mplot/RodVisual.h @@ -1,12 +1,16 @@ -#pragma once +module; +#include #include #include +export module mplot.rodvisual; + import sm.vec; -import mplot.visualmodel; +import mplot.gl.version; +export import mplot.visualmodel; -namespace mplot +export namespace mplot { //! This class creates the vertices for a cylindrical 'rod' in a 3D scene. template From 47115bcdd49af574a9a44c281f6dde1da2c05e03 Mon Sep 17 00:00:00 2001 From: Seb James Date: Sun, 8 Mar 2026 21:30:38 +0000 Subject: [PATCH 033/106] Back to just one CoordArrows, and that one derived from VisualModel --- examples/CMakeLists.txt | 2 + mplot/CoordArrows.h | 586 ++-------------------------------------- mplot/CoordsVisual.h | 173 ------------ mplot/VisualModel.h | 2 +- mplot/VisualOwnable.h | 4 +- mplot/VisualTextModel.h | 2 - 6 files changed, 23 insertions(+), 746 deletions(-) delete mode 100644 mplot/CoordsVisual.h diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index e639215c..0ec28a67 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -274,6 +274,7 @@ endif() # Any example that uses sm::hexgrid or sm::cartgrid requires # libarmadillo (because the classes use sm::BezCurve). # +if(0) if(ARMADILLO_FOUND) add_executable(showcase showcase.cpp) target_sources(showcase PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} @@ -324,6 +325,7 @@ if(ARMADILLO_FOUND) ) target_link_libraries(showcase OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) endif(ARMADILLO_FOUND) +endif (0) if(0) # During development diff --git a/mplot/CoordArrows.h b/mplot/CoordArrows.h index 9205936c..019f48ca 100644 --- a/mplot/CoordArrows.h +++ b/mplot/CoordArrows.h @@ -1,56 +1,40 @@ /*! * \file * - * Defines a non-VisualModel coordinate arrow class for internal use in the scene (bottom left corner). + * Defines a coordinate arrow class based on VisualModel * * \author Seb James * \date 2019 */ module; -#if defined __gl3_h_ || defined __gl_h_ // could get a fuller list from glfw.h -// GL headers appear to have been externally included. -#else -# include -#endif // GL headers - #include -#include -#include -#include - -#include +#include export module mplot.coordarrows; -import mplot.visualtextmodel; -import mplot.textfeatures; -import mplot.visualfont; -import mplot.visualcommon; -import mplot.colour; -import mplot.gl.version; -import mplot.gl.util; import sm.vec; -import sm.mat; -import sm.flags; +import mplot.gl.version; +export import mplot.visualmodel; +export import mplot.textfeatures; +import mplot.visualfont; +export import mplot.colour; export namespace mplot { - // State/options flags - enum class ca_bools : uint32_t { postVertexInitRequired, hide }; - //! This class creates the vertices for a set of coordinate arrows to be rendered //! in a 3-D scene. template - class CoordArrows + class CoordArrows : public VisualModel { public: - CoordArrows() {} - CoordArrows (const sm::vec& offset) { this->viewmatrix.translate (offset); } + CoordArrows() : mplot::VisualModel() {} + CoordArrows (const sm::vec& offset) : mplot::VisualModel(offset) {} //! Must make the boilerplate bindmodel call before calling init() (for text handling) void init (const sm::vec _lengths, const float _thickness, const float _em) { + this->compute_bb (false); this->lengths = _lengths; this->thickness = _thickness; this->em = _em; @@ -59,72 +43,12 @@ export namespace mplot //! You can call this AS well as the first init overload to set the axis vectors void init (const sm::vec _x, const sm::vec _y, const sm::vec _z) { + this->compute_bb (false); this->x_axis = _x; this->y_axis = _y; this->z_axis = _z; } - // State/options flags - constexpr sm::flags flags_defaults() - { - sm::flags _flags; - _flags.reset(); // all false - return _flags; - } - sm::flags flags = flags_defaults(); - - // The hide attribute accessors - void setHide (const bool _h = true) { this->flags.set (ca_bools::hide, _h); } - void toggleHide() { this->flags.flip (ca_bools::hide); } - float hidden() const { return this->flags.test (ca_bools::hide); } - - void setSceneMatrixTexts (const sm::mat& sv) - { - auto ti = this->texts.begin(); - while (ti != this->texts.end()) { (*ti)->setSceneMatrix (sv); ti++; } - } - - //! When setting the scene matrix, also have to set the text's scene matrices. - void setSceneMatrix (const sm::mat& sv) - { - this->scenematrix = sv; - this->setSceneMatrixTexts (sv); - } - - void setSceneTranslationTexts (const sm::vec& v0) - { - auto ti = this->texts.begin(); - while (ti != this->texts.end()) { (*ti)->setSceneTranslation (v0); ti++; } - } - - //! Set a translation into the scene and into any child texts - void setSceneTranslation (const sm::vec& v0) - { - this->scenematrix.set_identity(); - this->scenematrix.translate (v0); - this->setSceneTranslationTexts (v0); - } - - void setViewRotationTexts (const sm::quaternion& r) - { - // See VisualModel for explanation - auto ti = this->texts.begin(); - while (ti != this->texts.end()) { - (*ti)->setSceneRotation (r); - (*ti)->setViewRotation (r.invert()); - ti++; - } - } - //! Set a rotation (only) into the view - void setViewRotation (const sm::quaternion& r) - { - sm::vec<> os = this->viewmatrix.translation(); - this->viewmatrix.set_identity(); - this->viewmatrix.translate (os); - this->viewmatrix.rotate (r); - this->setViewRotationTexts (r); - } - //! Make sure coord arrow colours are ok on the given background colour. Call this *after* finalize. void setColourForBackground (const std::array& bgcolour) { @@ -132,28 +56,24 @@ export namespace mplot std::array cscol = { 1.0f - bgcolour[0], 1.0f - bgcolour[1], 1.0f - bgcolour[2] }; if (cscol != this->centresphere_col) { this->centresphere_col = cscol; - this->reinit(); + this->reinit(); // sets context, does not release it + // Give the text labels a suitable, visible colour - // Don't worry about context, assume its ok. + mplot::VisualResources::i().setContext (this->parentVis); auto ti = this->texts.begin(); while (ti != this->texts.end()) { (*ti)->setVisibleOn (bgcolour); ti++; } + mplot::VisualResources::i().releaseContext(); } } - std::unique_ptr> makeVisualTextModel(const mplot::TextFeatures& tfeatures) - { - auto tmup = std::make_unique> (tfeatures); - tmup->set_parent (this->parentVis); - return tmup; - } - void initAxisLabels() { if (this->em > 0.0f) { + mplot::VisualResources::i().setContext (this->parentVis); mplot::TextFeatures tfca(this->em, 48, false, mplot::colour::black, mplot::VisualFont::DVSansItalic); // These texts are black by default @@ -174,6 +94,8 @@ export namespace mplot auto vtm3 = this->makeVisualTextModel (tfca); vtm3->setupText (this->z_label, toffset); this->texts.push_back (std::move(vtm3)); + + mplot::VisualResources::i().releaseContext(); } } @@ -218,67 +140,6 @@ export namespace mplot this->initAxisLabels(); } - void finalize() - { - this->initializeVertices(); - this->flags.set (ca_bools::postVertexInitRequired, true); - } - - uint32_t gprog = 0; - - void render() // not final - { - if (this->hidden() == true) { return; } - - // Execute post-vertex init at render, as GL should be available. - if (this->flags.test (ca_bools::postVertexInitRequired) == true) { this->postVertexInit(); } - - GLint prev_shader = 0; - - this->glfn->GetIntegerv (GL_CURRENT_PROGRAM, &prev_shader); - // Ensure the correct program is in play for this VisualModel - this->glfn->UseProgram (gprog); - - if (!this->indices.empty()) { - - this->glfn->PolygonMode (GL_FRONT_AND_BACK, GL_FILL); // filled not wireframe - - // It is only necessary to bind the vertex array object before rendering - // (not the vertex buffer objects) - this->glfn->BindVertexArray (this->vao); - - GLint loc_a = this->glfn->GetUniformLocation (gprog, static_cast("alpha")); - if (loc_a != -1) { this->glfn->Uniform1f (loc_a, 1.0f); } - - // The scene-view matrix - GLint loc_v = this->glfn->GetUniformLocation (gprog, static_cast("v_matrix")); - if (loc_v != -1) { this->glfn->UniformMatrix4fv (loc_v, 1, GL_FALSE, this->scenematrix.arr.data()); } - - // the model-view matrix - GLint loc_m = this->glfn->GetUniformLocation (gprog, static_cast("m_matrix")); - if (loc_m != -1) { this->glfn->UniformMatrix4fv (loc_m, 1, GL_FALSE, this->viewmatrix.arr.data()); } - - // the instance scaling matrix (applied to all instances) - GLint loc_s = this->glfn->GetUniformLocation (gprog, static_cast("s_matrix")); - constexpr auto idmat = sm::mat::identity(); - if (loc_s != -1) { this->glfn->UniformMatrix4fv (loc_s, 1, GL_FALSE, idmat.arr.data()); } - - // Draw the triangles - this->glfn->DrawElements (GL_TRIANGLES, static_cast(this->indices.size()), GL_UNSIGNED_INT, 0); - - // Unbind the VAO - this->glfn->BindVertexArray(0); - } - mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); - - // Now render any VisualTextModels - auto ti = this->texts.begin(); - while (ti != this->texts.end()) { (*ti)->render(); ti++; } - - this->glfn->UseProgram (prev_shader); - mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); - } - //! Length multipliers that can be applied to ux, uy and uz sm::vec lengths = { 1.0f, 1.0f, 1.0f }; @@ -310,415 +171,6 @@ export namespace mplot std::string x_label = "X"; std::string y_label = "Y"; std::string z_label = "Z"; - - GladGLContext* glfn = nullptr; - - // The mplot::Visual in which this model exists. - uint32_t parentVis = std::numeric_limits::max(); - - protected: - - //! The current indices index - uint32_t idx = 0u; - - //! The model-specific view matrix. Used to transform the pose of the model in the scene. - sm::mat viewmatrix = {}; - - /*! - * The scene view matrix. Each VisualModel has a copy of the scenematrix. It's set in - * Visual::render. Different VisualModels may have different scenematrices (for example, the - * CoordArrows has a different scenematrix from other VisualModels, and models marked - * 'twodimensional' also have a different scenematrix). - */ - sm::mat scenematrix = {}; - - //! Contains the positions within the vbo array of the different vertex buffer objects - enum VBOPos { posnVBO, normVBO, colVBO, idxVBO, numVBO }; - - /* - * Compute positions and colours of vertices for the hexes and store in these: - */ - - //! The OpenGL Vertex Array Object - uint32_t vao = 0; - - //! Vertex Buffer Objects stored in an array - std::unique_ptr vbos; - - //! CPU-side data for indices - std::vector indices = {}; - //! CPU-side data for vertex positions - std::vector vertexPositions = {}; - //! CPU-side data for vertex normals - std::vector vertexNormals = {}; - //! CPU-side data for vertex colours - std::vector vertexColors = {}; - - //! Common code to call after the vertices have been set up. GL has to have been initialised. - void postVertexInit() - { - // Do gl memory allocation of vertex array once only - if (this->vbos == nullptr) { - // Create vertex array object - this->glfn->GenVertexArrays (1, &this->vao); // Safe for OpenGL 4.4- - } - this->glfn->BindVertexArray (this->vao); - - // Create the vertex buffer objects (once only) - if (this->vbos == nullptr) { - this->vbos = std::make_unique(this->numVBO); - this->glfn->GenBuffers (this->numVBO, this->vbos.get()); // OpenGL 4.4- safe - } - - // Set up the indices buffer - bind and buffer the data in this->indices - this->glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos[this->idxVBO]); - - std::size_t sz = this->indices.size() * sizeof(uint32_t); - this->glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices.data(), GL_STATIC_DRAW); - - // Binds data from the "C++ world" to the OpenGL shader world for - // "position", "normalin" and "color" - // (bind, buffer and set vertex array object attribute) - this->setupVBO (this->vbos[this->posnVBO], this->vertexPositions, visgl::posnLoc); - this->setupVBO (this->vbos[this->normVBO], this->vertexNormals, visgl::normLoc); - this->setupVBO (this->vbos[this->colVBO], this->vertexColors, visgl::colLoc); - - // Unbind only the vertex array (not the buffers, that causes GL_INVALID_ENUM errors) - this->glfn->BindVertexArray(0); // carefully unbind and rebind - mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); - - this->flags.set (ca_bools::postVertexInitRequired, false); // Maybe just a bool here - } - - //! Re-create the model - called after updating data - void reinit() - { - // Fixme: Better not to clear, then repeatedly pushback here: - this->vertexPositions.clear(); - this->vertexNormals.clear(); - this->vertexColors.clear(); - this->indices.clear(); - - // NB: Do NOT call clearTexts() here! We're only updating the model itself. - this->idx = 0u; - this->initializeVertices(); - this->reinit_buffers(); - } - - /*! - * Re-initialize the buffers. Client code might have appended to - * vertexPositions/Colors/Normals and indices before calling this method. - */ - void reinit_buffers() - { - // Note that we do not worry about setting context here, we assume the parent Visual has the context - if (this->flags.test (ca_bools::postVertexInitRequired) == true) { this->postVertexInit(); } - - // Now re-set up the VBOs - this->glfn->BindVertexArray (this->vao); // carefully unbind and rebind - this->glfn->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, this->vbos[this->idxVBO]); // carefully unbind and rebind - - std::size_t sz = this->indices.size() * sizeof(uint32_t); - this->glfn->BufferData (GL_ELEMENT_ARRAY_BUFFER, sz, this->indices.data(), GL_STATIC_DRAW); - this->setupVBO (this->vbos[this->posnVBO], this->vertexPositions, visgl::posnLoc); - this->setupVBO (this->vbos[this->normVBO], this->vertexNormals, visgl::normLoc); - this->setupVBO (this->vbos[this->colVBO], this->vertexColors, visgl::colLoc); - - this->glfn->BindVertexArray(0); // carefully unbind and rebind - mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); // carefully unbind and rebind - } - - //! A vector of pointers to text models that should be rendered. - std::vector>> texts; - - //! Set up a vertex buffer object - bind, buffer and set vertex array object attribute - void setupVBO (uint32_t& buf, std::vector& dat, unsigned int bufferAttribPosition) - { - std::size_t sz = dat.size() * sizeof(float); - - this->glfn->BindBuffer (GL_ARRAY_BUFFER, buf); - mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); - this->glfn->BufferData (GL_ARRAY_BUFFER, sz, dat.data(), GL_STATIC_DRAW); - mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); - this->glfn->VertexAttribPointer (bufferAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0)); - mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); - this->glfn->EnableVertexAttribArray (bufferAttribPosition); - mplot::gl::Util::checkError (__FILE__, __LINE__, this->glfn); - } - - void vertex_push (const float& x, const float& y, const float& z, std::vector& vp) - { vp.emplace_back (x); vp.emplace_back (y); vp.emplace_back (z); } - template requires (N == 3 || N == 4) - void vertex_push (const std::array& arr, std::vector& vp) - { vp.emplace_back (arr[0]); vp.emplace_back (arr[1]); vp.emplace_back (arr[2]); } - template requires (N == 3 || N == 4) - void vertex_push (const sm::vec& vec, std::vector& vp) - { vp.emplace_back (vec[0]); vp.emplace_back (vec[1]); vp.emplace_back (vec[2]); } - - /*! - * Sphere, 1 colour version. - * - * \param so The sphere offset. Where to place this sphere... - * \param sc The sphere colour. - * \param r Radius of the sphere - * \param rings Number of rings used to render the sphere - * \param segments Number of segments used to render the sphere - */ - void computeSphere (sm::vec so, std::array sc, - float r = 1.0f, int rings = 10, int segments = 12) - { - float rings0 = -sm::mathconst::pi_over_2; - float _z0 = std::sin(rings0); - float z0 = r * _z0; - float r0 = std::cos(rings0); - float rings1 = sm::mathconst::pi * (-0.5f + 1.0f / rings); - float _z1 = std::sin(rings1); - float z1 = r * _z1; - float r1 = std::cos(rings1); - - this->vertex_push (so[0]+0.0f, so[1]+0.0f, so[2]+z0, this->vertexPositions); - this->vertex_push (0.0f, 0.0f, -1.0f, this->vertexNormals); - this->vertex_push (sc, this->vertexColors); - - uint32_t capMiddle = this->idx++; - uint32_t ringStartIdx = this->idx; - uint32_t lastRingStartIdx = this->idx; - - bool firstseg = true; - for (int j = 0; j < segments; j++) { - float segment = sm::mathconst::two_pi * static_cast(j) / segments; - float x = std::cos(segment); - float y = std::sin(segment); - - float _x1 = x*r1; - float x1 = _x1*r; - float _y1 = y*r1; - float y1 = _y1*r; - - this->vertex_push (so[0]+x1, so[1]+y1, so[2]+z1, this->vertexPositions); - this->vertex_push (_x1, _y1, _z1, this->vertexNormals); - this->vertex_push (sc, this->vertexColors); - - if (!firstseg) { - this->indices.push_back (capMiddle); - this->indices.push_back (this->idx-1); - this->indices.push_back (this->idx++); - } else { - this->idx++; - firstseg = false; - } - } - this->indices.push_back (capMiddle); - this->indices.push_back (this->idx-1); - this->indices.push_back (capMiddle+1); - - for (int i = 2; i < rings; i++) { - - rings0 = sm::mathconst::pi * (-0.5f + static_cast(i) / rings); - _z0 = std::sin(rings0); - z0 = r * _z0; - r0 = std::cos(rings0); - - for (int j = 0; j < segments; j++) { - - float segment = sm::mathconst::two_pi * static_cast(j) / segments; - float x = std::cos(segment); - float y = std::sin(segment); - - float _x0 = x*r0; - float x0 = _x0*r; - float _y0 = y*r0; - float y0 = _y0*r; - - this->vertex_push (so[0]+x0, so[1]+y0, so[2]+z0, this->vertexPositions); - this->vertex_push (_x0, _y0, _z0, this->vertexNormals); - this->vertex_push (sc, this->vertexColors); - - if (j == segments - 1) { - this->indices.push_back (ringStartIdx++); - this->indices.push_back (this->idx); - this->indices.push_back (lastRingStartIdx); - this->indices.push_back (lastRingStartIdx); - this->indices.push_back (this->idx++); - this->indices.push_back (lastRingStartIdx+segments); - } else { - this->indices.push_back (ringStartIdx++); - this->indices.push_back (this->idx); - this->indices.push_back (ringStartIdx); - this->indices.push_back (ringStartIdx); - this->indices.push_back (this->idx++); - this->indices.push_back (this->idx); - } - } - lastRingStartIdx += segments; - } - - rings0 = sm::mathconst::pi_over_2; - _z0 = std::sin(rings0); - z0 = r * _z0; - r0 = std::cos(rings0); - - this->vertex_push (so[0]+0.0f, so[1]+0.0f, so[2]+z0, this->vertexPositions); - this->vertex_push (0.0f, 0.0f, 1.0f, this->vertexNormals); - this->vertex_push (sc, this->vertexColors); - capMiddle = this->idx++; - firstseg = true; - - ringStartIdx = lastRingStartIdx; - for (int j = 0; j < segments; j++) { - if (j != segments - 1) { - this->indices.push_back (capMiddle); - this->indices.push_back (ringStartIdx++); - this->indices.push_back (ringStartIdx); - } else { - this->indices.push_back (capMiddle); - this->indices.push_back (ringStartIdx); - this->indices.push_back (lastRingStartIdx); - } - } - } // end of sphere calculation - - /*! - * Create a tube from \a start to \a end, with radius \a r and a colour which - * transitions from the colour \a colStart to \a colEnd. - * - * \param idx The index into the 'vertex array' - * \param start The start of the tube - * \param end The end of the tube - * \param colStart The tube starting colour - * \param colEnd The tube's ending colour - * \param r Radius of the tube - * \param segments Number of segments used to render the tube - */ - void computeTube (sm::vec start, sm::vec end, - std::array colStart, std::array colEnd, - float r = 1.0f, int segments = 12) - { - this->computeFlaredTube (start, end, colStart, colEnd, r, r, segments); - } - - void computeFlaredTube (sm::vec start, sm::vec end, - std::array colStart, std::array colEnd, - float r = 1.0f, int segments = 12, float flare = 0.0f) - { - sm::vec v = end - start; - float l = v.length(); - float r_add = l * std::tan (std::abs(flare)) * (flare > 0.0f ? 1.0f : -1.0f); - float r_end = r + r_add; - this->computeFlaredTube (start, end, colStart, colEnd, r, r_end, segments); - } - - void computeFlaredTube (sm::vec start, sm::vec end, - std::array colStart, std::array colEnd, - float r = 1.0f, float r_end = 1.0f, int segments = 12) - { - sm::vec vstart = start; - sm::vec vend = end; - sm::vec v = vend - vstart; - v.renormalize(); - - sm::vec rand_vec; - rand_vec.randomize(); - sm::vec inplane = rand_vec.cross(v); - inplane.renormalize(); - - sm::vec v_x_inplane = v.cross(inplane); - - this->vertex_push (vstart, this->vertexPositions); - this->vertex_push (-v, this->vertexNormals); - this->vertex_push (colStart, this->vertexColors); - - for (int j = 0; j < segments; j++) { - float t = j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = inplane * std::sin(t) * r + v_x_inplane * std::cos(t) * r; - this->vertex_push (vstart+c, this->vertexPositions); - this->vertex_push (-v, this->vertexNormals); - this->vertex_push (colStart, this->vertexColors); - } - - for (int j = 0; j < segments; j++) { - float t = j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = inplane * std::sin(t) * r + v_x_inplane * std::cos(t) * r; - this->vertex_push (vstart+c, this->vertexPositions); - c.renormalize(); - this->vertex_push (c, this->vertexNormals); - this->vertex_push (colStart, this->vertexColors); - } - - for (int j = 0; j < segments; j++) { - float t = (float)j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = inplane * std::sin(t) * r_end + v_x_inplane * std::cos(t) * r_end; - this->vertex_push (vend+c, this->vertexPositions); - c.renormalize(); - this->vertex_push (c, this->vertexNormals); - this->vertex_push (colEnd, this->vertexColors); - } - - for (int j = 0; j < segments; j++) { - float t = (float)j * sm::mathconst::two_pi / static_cast(segments); - sm::vec c = inplane * std::sin(t) * r_end + v_x_inplane * std::cos(t) * r_end; - this->vertex_push (vend+c, this->vertexPositions); - this->vertex_push (v, this->vertexNormals); - this->vertex_push (colEnd, this->vertexColors); - } - - this->vertex_push (vend, this->vertexPositions); - this->vertex_push (v, this->vertexNormals); - this->vertex_push (colEnd, this->vertexColors); - - int nverts = (segments * 4) + 2; - - uint32_t capMiddle = this->idx; - uint32_t capStartIdx = this->idx + 1u; - uint32_t endMiddle = this->idx + static_cast(nverts) - 1u; - uint32_t endStartIdx = capStartIdx + (3u * segments); - - for (int j = 0; j < segments-1; j++) { - this->indices.push_back (capMiddle); - this->indices.push_back (capStartIdx + j); - this->indices.push_back (capStartIdx + 1 + j); - } - - this->indices.push_back (capMiddle); - this->indices.push_back (capStartIdx + segments - 1); - this->indices.push_back (capStartIdx); - - for (int lsection = 0; lsection < 3; ++lsection) { - capStartIdx = this->idx + 1 + lsection*segments; - endStartIdx = capStartIdx + segments; - for (int j = 0; j < segments; j++) { - this->indices.push_back (capStartIdx + j); - if (j == (segments-1)) { - this->indices.push_back (capStartIdx); - } else { - this->indices.push_back (capStartIdx + 1 + j); - } - this->indices.push_back (endStartIdx + j); - this->indices.push_back (endStartIdx + j); - if (j == (segments-1)) { - this->indices.push_back (endStartIdx); - } else { - this->indices.push_back (endStartIdx + 1 + j); - } - if (j == (segments-1)) { - this->indices.push_back (capStartIdx); - } else { - this->indices.push_back (capStartIdx + j + 1); - } - } - } - - for (int j = 0; j < segments-1; j++) { - this->indices.push_back (endMiddle); - this->indices.push_back (endStartIdx + j); - this->indices.push_back (endStartIdx + 1 + j); - } - this->indices.push_back (endMiddle); - this->indices.push_back (endStartIdx + segments - 1); - this->indices.push_back (endStartIdx); - - this->idx += nverts; - } // end computeFlaredTube with randomly initialized end vertices }; } // namespace mplot diff --git a/mplot/CoordsVisual.h b/mplot/CoordsVisual.h deleted file mode 100644 index b24e6820..00000000 --- a/mplot/CoordsVisual.h +++ /dev/null @@ -1,173 +0,0 @@ -/*! - * \file - * - * Defines a coordinate arrow class based on VisualModel - * - * \author Seb James - * \date 2019 - */ -#pragma once - -#include - -import sm.vec; - -#include -#include -#include - -namespace mplot -{ - //! This class creates the vertices for a set of coordinate arrows to be rendered - //! in a 3-D scene. - template - class CoordsVisual : public VisualModel - { - public: - CoordsVisual() : mplot::VisualModel() {} - CoordsVisual (const sm::vec& offset) : mplot::VisualModel(offset) {} - - //! Must make the boilerplate bindmodel call before calling init() (for text handling) - void init (const sm::vec _lengths, const float _thickness, const float _em) - { - this->compute_bb (false); - this->lengths = _lengths; - this->thickness = _thickness; - this->em = _em; - } - - //! You can call this AS well as the first init overload to set the axis vectors - void init (const sm::vec _x, const sm::vec _y, const sm::vec _z) - { - this->compute_bb (false); - this->x_axis = _x; - this->y_axis = _y; - this->z_axis = _z; - } - - //! Make sure coord arrow colours are ok on the given background colour. Call this *after* finalize. - void setColourForBackground (const std::array& bgcolour) - { - // For now, only worry about the centresphere: - std::array cscol = { 1.0f - bgcolour[0], 1.0f - bgcolour[1], 1.0f - bgcolour[2] }; - if (cscol != this->centresphere_col) { - this->centresphere_col = cscol; - this->reinit(); // sets context, does not release it - - // Give the text labels a suitable, visible colour - if (this->setContext != nullptr) { this->setContext (this->parentVis); } - auto ti = this->texts.begin(); - while (ti != this->texts.end()) { - (*ti)->setVisibleOn (bgcolour); - ti++; - } - if (this->releaseContext != nullptr) { this->releaseContext (this->parentVis); } - } - } - - void initAxisLabels() - { - if (this->em > 0.0f) { - - if (this->setContext != nullptr) { this->setContext (this->parentVis); } // For VisualTextModel - - mplot::TextFeatures tfca(this->em, 48, false, mplot::colour::black, mplot::VisualFont::DVSansItalic); - - // These texts are black by default - sm::vec _offset = this->viewmatrix.translation(); - sm::vec toffset = {}; - toffset = _offset + this->x_axis * this->lengths[0]; - toffset[0] += this->em; - auto vtm1 = this->makeVisualTextModel (tfca); - vtm1->setupText (this->x_label, toffset); - this->texts.push_back (std::move(vtm1)); - toffset = _offset + this->y_axis * this->lengths[1]; - toffset[0] += this->em; - auto vtm2 = this->makeVisualTextModel (tfca); - vtm2->setupText (this->y_label, toffset); - this->texts.push_back (std::move(vtm2)); - toffset = _offset + this->z_axis * this->lengths[2]; - toffset[0] += this->em; - auto vtm3 = this->makeVisualTextModel (tfca); - vtm3->setupText (this->z_label, toffset); - this->texts.push_back (std::move(vtm3)); - - if (this->releaseContext != nullptr) { this->releaseContext (this->parentVis); } - } - } - - //! Initialize vertex buffer objects and vertex array object. - void initializeVertices() - { - this->vertexPositions.clear(); - this->vertexNormals.clear(); - this->vertexColors.clear(); - this->indices.clear(); - this->idx = 0; - - // Draw four spheres to make up the coord frame, with centre at 0,0,0 - sm::vec reloffset = {}; - static constexpr sm::vec zerocoord = { 0.0f, 0.0f, 0.0f }; - this->computeSphere (zerocoord, centresphere_col, this->thickness * this->lengths[0] / 20.0f); - - // x - reloffset = this->x_axis * this->lengths[0]; - this->computeSphere (reloffset, x_axis_col, (this->thickness * this->lengths[0] / 40.0f) * endsphere_size); - this->computeTube (zerocoord, reloffset, x_axis_col, x_axis_col, this->thickness * this->lengths[0] / 80.0f); - if (showneg) { - this->computeTube (zerocoord, -reloffset, x_axis_neg, x_axis_neg, this->thickness * this->lengths[0] / 80.0f); - } - - // y - reloffset = this->y_axis * this->lengths[1]; - this->computeSphere (reloffset, y_axis_col, (this->thickness * this->lengths[0] / 40.0f) * endsphere_size); - this->computeTube (zerocoord, reloffset, y_axis_col, y_axis_col, this->thickness * this->lengths[0] / 80.0f); - if (showneg) { - this->computeTube (zerocoord, -reloffset, y_axis_neg, y_axis_neg, this->thickness * this->lengths[0] / 80.0f); - } - - // z - reloffset = this->z_axis * this->lengths[2]; - this->computeSphere (reloffset, z_axis_col, (this->thickness * this->lengths[0] / 40.0f) * endsphere_size); - this->computeTube (zerocoord, reloffset, z_axis_col, z_axis_col, this->thickness * this->lengths[0] / 80.0f); - if (showneg) { - this->computeTube (zerocoord, -reloffset, z_axis_neg, z_axis_neg, this->thickness * this->lengths[0] / 80.0f); - } - - this->initAxisLabels(); - } - - //! Length multipliers that can be applied to ux, uy and uz - sm::vec lengths = { 1.0f, 1.0f, 1.0f }; - - //! The axes for the coordinate arrows. A simple right handed coordinate system aligned with - //! the 'real' world coordinate system by default. - sm::vec x_axis = { 1.0f, 0.0f, 0.0f }; - sm::vec y_axis = { 0.0f, 1.0f, 0.0f }; - sm::vec z_axis = { 0.0f, 0.0f, 1.0f }; - - //! A thickness scaling factor, to apply to the arrows. - float thickness = 1.0f; - //! a multiplier on the end spheres - float endsphere_size = 1.0f; - //! m size for text labels - float em = 0.0f; - - //! The colours of the arrows, and of the centre sphere (where default of black is suitable - //! for a white background) - std::array centresphere_col = mplot::colour::black; - std::array x_axis_col = mplot::colour::crimson; - std::array y_axis_col = mplot::colour::springgreen2; - std::array z_axis_col = mplot::colour::blue2; - - bool showneg = false; - std::array x_axis_neg = mplot::colour::raspberry; - std::array y_axis_neg = mplot::colour::darkseagreen3; - std::array z_axis_neg = mplot::colour::steelblue3; - - std::string x_label = "X"; - std::string y_label = "Y"; - std::string z_label = "Z"; - }; - -} // namespace mplot diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index 04327512..aa4aca39 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -49,7 +49,7 @@ import sm.base64; // Need to import common here import mplot.visualcommon; -import mplot.visualresources; +export import mplot.visualresources; import mplot.visualtextmodel; import mplot.colour; import mplot.gl.version; diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index 385e33ea..b316d550 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -647,9 +647,7 @@ export namespace mplot // Use coordArrowsOffset to set the location of the CoordArrows *scene* this->coordArrows = std::make_unique>(); - this->coordArrows->glfn = this->glfn; - this->coordArrows->gprog = this->shaders.gprog; - this->coordArrows->parentVis = this->visual_id; + this->coordArrows->set_parent (this->visual_id); // And NOW we can proceed to init (lengths, thickness, em size for labels): this->coordArrows->init (sm::vec<>{0.1f, 0.1f, 0.1f}, 1.0f, 0.01f); this->coordArrows->finalize(); // VisualModel::finalize releases context (normally this is the right thing)... diff --git a/mplot/VisualTextModel.h b/mplot/VisualTextModel.h index 3913583a..0666ac62 100644 --- a/mplot/VisualTextModel.h +++ b/mplot/VisualTextModel.h @@ -194,8 +194,6 @@ export namespace mplot { constexpr bool debug_textquads = false; - std::cout << "Accessing VisualResources, parentVis is " << this->parentVis << std::endl; - if (this->face == nullptr) { GladGLContext* _glfn = mplot::VisualResources::i().get_glfn (this->parentVis); this->face = VisualResources::i().getVisualFace (this->tfeatures, this->parentVis, _glfn); From 6fa7c60cbd3901f096d86c75cd46e9581a8634f7 Mon Sep 17 00:00:00 2001 From: Seb James Date: Sun, 8 Mar 2026 21:39:16 +0000 Subject: [PATCH 034/106] Modularizes VectorVisual --- examples/CMakeLists.txt | 43 ++++++++++++++++++++++++++++++++++++++--- examples/vectorvis.cpp | 20 +++++++++++-------- mplot/VectorVisual.h | 12 +++++++----- mplot/Visual.h | 5 ++--- mplot/VisualModel.h | 8 ++++---- 5 files changed, 65 insertions(+), 23 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 0ec28a67..1ef03167 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -58,6 +58,8 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h + ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.h + PROPERTIES LANGUAGE CXX ) @@ -134,6 +136,44 @@ target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/maths/sm/vvec) target_link_libraries(rod OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) +add_executable(vectorvis vectorvis.cpp) +target_sources(vectorvis PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES + ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/gl/version.h + ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h + ${PROJECT_SOURCE_DIR}/mplot/colour.h + ${PROJECT_SOURCE_DIR}/mplot/win_t.h + ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h + ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h + ${PROJECT_SOURCE_DIR}/mplot/Visual.h + ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h + ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h + ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h + ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h + ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h + ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h + ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/maths/sm/util + ${PROJECT_SOURCE_DIR}/maths/sm/base64 + ${PROJECT_SOURCE_DIR}/maths/sm/crc32 + ${PROJECT_SOURCE_DIR}/maths/sm/flags + ${PROJECT_SOURCE_DIR}/maths/sm/algo + ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/random + ${PROJECT_SOURCE_DIR}/maths/sm/vec + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/geometry + ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/vvec) +target_link_libraries(vectorvis OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) + add_executable(graph1 graph1.cpp) target_sources(graph1 PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES @@ -523,9 +563,6 @@ target_link_libraries(logisticmap OpenGL::GL glfw Freetype::Freetype) add_executable(quiver quiver.cpp) target_link_libraries(quiver OpenGL::GL glfw Freetype::Freetype) -add_executable(vectorvis vectorvis.cpp) -target_link_libraries(vectorvis OpenGL::GL glfw Freetype::Freetype) - add_executable(rotating_models rotating_models.cpp) target_link_libraries(rotating_models OpenGL::GL glfw Freetype::Freetype) diff --git a/examples/vectorvis.cpp b/examples/vectorvis.cpp index 4e516192..2fe9b7e4 100644 --- a/examples/vectorvis.cpp +++ b/examples/vectorvis.cpp @@ -5,14 +5,18 @@ #include #include #include +#include -#include -#include -#include +import sm.vec; +import sm.quaternion; +import sm.mat; -#include -#include -#include +import mplot.visual; +import mplot.colour; +import mplot.colourmap; +import mplot.textfeatures; + +import mplot.vectorvisual; int main() { @@ -24,7 +28,7 @@ int main() sm::vec offset = {1,0,0}; auto vvm = std::make_unique>(offset); - v.bindmodel (vvm); + vvm->set_parent (v.get_id()); vvm->thevec = {1,1,1}; vvm->fixed_colour = true; vvm->single_colour = mplot::colour::crimson; @@ -33,7 +37,7 @@ int main() auto ptr = v.addVisualModel (vvm); vvm = std::make_unique>(-offset); - v.bindmodel (vvm); + vvm->set_parent (v.get_id()); vvm->thevec = {1,1,1}; vvm->fixed_colour = true; vvm->single_colour = mplot::colour::royalblue; diff --git a/mplot/VectorVisual.h b/mplot/VectorVisual.h index 01272d55..91a24d1e 100644 --- a/mplot/VectorVisual.h +++ b/mplot/VectorVisual.h @@ -1,16 +1,18 @@ -#pragma once +module; /*! * \file Declares VectorVisual to visualize a vector. */ #include + +export module mplot.vectorvisual; + import sm.vec; -#include -#include -#include +import mplot.visualmodel; +import mplot.colourmap; -namespace mplot +export namespace mplot { //! How should the visualized vector go? Does it start at the origin? If so, it goes 'from' //! the origin; FromOrigin. Does it instead sit on top of the origin (OnOrigin)? diff --git a/mplot/Visual.h b/mplot/Visual.h index 18583a85..dafee595 100644 --- a/mplot/Visual.h +++ b/mplot/Visual.h @@ -28,14 +28,13 @@ module; export module mplot.visual; +export import mplot.gl.version; export import mplot.win_t; -import mplot.visualresources; +import mplot.visualresources; export import mplot.visualglfw; import mplot.visualownable; -import mplot.gl.version; - export namespace mplot { /*! diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index aa4aca39..1b4d14e6 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -48,11 +48,11 @@ import sm.flags; import sm.base64; // Need to import common here -import mplot.visualcommon; +export import mplot.gl.version; +export import mplot.visualcommon; export import mplot.visualresources; -import mplot.visualtextmodel; -import mplot.colour; -import mplot.gl.version; +export import mplot.visualtextmodel; +export import mplot.colour; import mplot.gl.util; import mplot.tools; From 0982102f787ce8ae4655997e00fcea531c7e948c Mon Sep 17 00:00:00 2001 From: Seb James Date: Sun, 8 Mar 2026 21:44:32 +0000 Subject: [PATCH 035/106] Modularizes InstancedScatterVisual --- examples/CMakeLists.txt | 3 +++ examples/breadcrumbs.cpp | 2 +- mplot/InstancedScatterVisual.h | 15 ++++++++------- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 1ef03167..19ffab99 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -60,6 +60,8 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.h + ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.h + PROPERTIES LANGUAGE CXX ) @@ -289,6 +291,7 @@ if(NOT APPLE) ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 diff --git a/examples/breadcrumbs.cpp b/examples/breadcrumbs.cpp index 3842525a..538b1167 100644 --- a/examples/breadcrumbs.cpp +++ b/examples/breadcrumbs.cpp @@ -15,7 +15,7 @@ import sm.vvec; import mplot.visual; import mplot.colourmap; -#include +import mplot.instancedscattervisual; #include // Instanced rendering requires OpenGL 4.3 or higher (for the SSBO) diff --git a/mplot/InstancedScatterVisual.h b/mplot/InstancedScatterVisual.h index 3595a3e5..afe1d8d2 100644 --- a/mplot/InstancedScatterVisual.h +++ b/mplot/InstancedScatterVisual.h @@ -4,20 +4,21 @@ * \author Seb James * \date 2025 */ -#pragma once +module; #include #include #include -import sm.vec; -import mplot.gl.version; +export module mplot.instancedscattervisual; + +export import sm.vec; +export import mplot.graphstyles; +export import mplot.colour; +export import mplot.visualmodel; import mplot.tools; -import mplot.visualmodel; -import mplot.graphstyles; -import mplot.colour; -namespace mplot +export namespace mplot { template class InstancedScatterVisual : public VisualModel From ada6c9cd56b6fd9de4f8fdbd64cc9380230e4aa7 Mon Sep 17 00:00:00 2001 From: Seb James Date: Sun, 8 Mar 2026 22:38:36 +0000 Subject: [PATCH 036/106] MOdularize EyeVisual and SphereVisual --- examples/CMakeLists.txt | 49 +++++++++++++++++++++++++++++++++++ examples/cray_eye.cpp | 16 +++++------- mplot/SphereVisual.h | 11 +++++--- mplot/compoundray/EyeVisual.h | 20 ++++++++------ mplot/jcvoronoi/jc_voronoi.h | 4 ++- 5 files changed, 78 insertions(+), 22 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 19ffab99..31d89655 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -60,6 +60,10 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.h + ${PROJECT_SOURCE_DIR}/mplot/SphereVisual.h + + ${PROJECT_SOURCE_DIR}/mplot/compoundray/EyeVisual.h + ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.h PROPERTIES LANGUAGE CXX @@ -88,6 +92,7 @@ target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 + ${PROJECT_SOURCE_DIR}/maths/sm/crc32 ${PROJECT_SOURCE_DIR}/maths/sm/flags ${PROJECT_SOURCE_DIR}/maths/sm/algo ${PROJECT_SOURCE_DIR}/maths/sm/range @@ -176,6 +181,50 @@ target_sources(vectorvis PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_ ${PROJECT_SOURCE_DIR}/maths/sm/vvec) target_link_libraries(vectorvis OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) +add_executable(cray_eye cray_eye.cpp) +target_sources(cray_eye PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES + ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/gl/version.h + ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h + ${PROJECT_SOURCE_DIR}/mplot/colour.h + ${PROJECT_SOURCE_DIR}/mplot/win_t.h + ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h + ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h + ${PROJECT_SOURCE_DIR}/mplot/Visual.h + ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h + ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h + ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h + ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h + ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h + ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h + ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + + ${PROJECT_SOURCE_DIR}/mplot/SphereVisual.h + ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.h + ${PROJECT_SOURCE_DIR}/mplot/compoundray/EyeVisual.h + + ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/maths/sm/util + ${PROJECT_SOURCE_DIR}/maths/sm/base64 + ${PROJECT_SOURCE_DIR}/maths/sm/crc32 + ${PROJECT_SOURCE_DIR}/maths/sm/winder + ${PROJECT_SOURCE_DIR}/maths/sm/centroid + ${PROJECT_SOURCE_DIR}/maths/sm/flags + ${PROJECT_SOURCE_DIR}/maths/sm/algo + ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/random + ${PROJECT_SOURCE_DIR}/maths/sm/vec + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/geometry + ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/vvec) +target_link_libraries(cray_eye OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) + add_executable(graph1 graph1.cpp) target_sources(graph1 PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES diff --git a/examples/cray_eye.cpp b/examples/cray_eye.cpp index 010af855..3aeda6e5 100644 --- a/examples/cray_eye.cpp +++ b/examples/cray_eye.cpp @@ -7,16 +7,14 @@ #include #include #include +#include -#include -#include -#include +import sm.vvec; +import sm.mat; -#include -#include -#include -#include -#include +import mplot.visual; +import mplot.colourmap; +import mplot.compoundray.eyevisual; int main (int argc, char** argv) { @@ -68,7 +66,7 @@ int main (int argc, char** argv) } auto eyevm = std::make_unique> (sm::vec<>{}, &ommatidiaColours, ommatidia.get()); - v.bindmodel (eyevm); + eyevm->set_parent (v.get_id()); eyevm->name = "CompoundRay Eye"; eyevm->show_cones = true; diff --git a/mplot/SphereVisual.h b/mplot/SphereVisual.h index 658bc4d4..c9d9a51d 100644 --- a/mplot/SphereVisual.h +++ b/mplot/SphereVisual.h @@ -1,13 +1,16 @@ /* * You just want a sphere visual model? Here it is. */ -#pragma once +module; #include -import sm.vec; -#include -namespace mplot +export module mplot.spherevisual; + +export import mplot.visualmodel; +export import sm.vec; + +export namespace mplot { //! This class creates the vertices for a simple sphere in a 3D scene. template diff --git a/mplot/compoundray/EyeVisual.h b/mplot/compoundray/EyeVisual.h index 3f1c5433..b2285162 100644 --- a/mplot/compoundray/EyeVisual.h +++ b/mplot/compoundray/EyeVisual.h @@ -1,22 +1,26 @@ // // A visualmodel to render a compound-ray compound eye. // - -#pragma once +module; #include #include #include -import sm.vec; +#include + +export module mplot.compoundray.eyevisual; + +export import sm.vec; import sm.mat; import sm.range; import sm.geometry; import sm.centroid; -#include -#include -#include -namespace mplot::compoundray +export import mplot.gl.version; +export import mplot.visualmodel; +import mplot.tools; + +export namespace mplot::compoundray { // This is a binary-compatible equivalent to struct Ommatidium from cameras/CompoundEyeDataTypes.h in compound-ray. // Use reinterpret_cast*>(ommatidia) if your ommatidia originate inside compound ray. @@ -29,7 +33,7 @@ namespace mplot::compoundray }; // Helper function. Read the compound-ray csv eye file into ommatidia. ommatidia should be a pointer to an allocate vector. - [[maybe_unused]] static std::vector* + [[maybe_unused]] std::vector* readEye (std::vector* ommatidia, const std::string& path) { if (ommatidia == nullptr) { return ommatidia; } diff --git a/mplot/jcvoronoi/jc_voronoi.h b/mplot/jcvoronoi/jc_voronoi.h index 1f5bc1f6..b6ad077c 100644 --- a/mplot/jcvoronoi/jc_voronoi.h +++ b/mplot/jcvoronoi/jc_voronoi.h @@ -19,6 +19,8 @@ #include #include // assert() #include // uintptr_t etc +#include // std::memset +#include #include #include import sm.vec; @@ -1262,7 +1264,7 @@ namespace jcv size_t memsize = sizeof(priorityqueue) + eventssize + sitessize + sizeof(context_internal) + 16u; // 16 bytes padding for alignment char* originalmem = (char*)allocfn (userallocctx, memsize); - memset (originalmem, 0, memsize); + std::memset (originalmem, 0, memsize); // align memory char* mem = (char*)align (originalmem, sizeof(void*)); From 90aa679b62a92d2eb809887ed0af510af911ea42 Mon Sep 17 00:00:00 2001 From: Seb James Date: Sun, 8 Mar 2026 22:55:03 +0000 Subject: [PATCH 037/106] Modularize NormalsVisual, VerticesVisual, all towards compiling antpov --- examples/CMakeLists.txt | 80 +++++++++++++++++++++++++++++++++++ examples/ellipsoid.cpp | 17 ++++---- examples/rod_with_normals.cpp | 19 ++++----- mplot/NormalsVisual.h | 15 ++++--- mplot/VerticesVisual.h | 8 ++-- mplot/Visual.h | 2 +- mplot/VisualOwnable.h | 18 ++++---- mplot/compoundray/interop.h | 11 +++-- mplot/fps/profiler.h | 6 ++- 9 files changed, 134 insertions(+), 42 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 31d89655..7cfaa91c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -62,6 +62,8 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/SphereVisual.h + ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.h + ${PROJECT_SOURCE_DIR}/mplot/compoundray/EyeVisual.h ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.h @@ -143,6 +145,84 @@ target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/maths/sm/vvec) target_link_libraries(rod OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) +add_executable(rod_with_normals rod_with_normals.cpp) +target_sources(rod_with_normals PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES + ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/gl/version.h + ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h + ${PROJECT_SOURCE_DIR}/mplot/colour.h + ${PROJECT_SOURCE_DIR}/mplot/win_t.h + ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h + ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h + ${PROJECT_SOURCE_DIR}/mplot/Visual.h + ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h + ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h + ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h + ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h + ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h + ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h + ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h + ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/maths/sm/util + ${PROJECT_SOURCE_DIR}/maths/sm/base64 + ${PROJECT_SOURCE_DIR}/maths/sm/crc32 + ${PROJECT_SOURCE_DIR}/maths/sm/flags + ${PROJECT_SOURCE_DIR}/maths/sm/algo + ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/random + ${PROJECT_SOURCE_DIR}/maths/sm/vec + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/geometry + ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/vvec) +target_link_libraries(rod_with_normals OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) + +add_executable(ellipsoid ellipsoid.cpp) +target_sources(ellipsoid PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES + ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/gl/version.h + ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h + ${PROJECT_SOURCE_DIR}/mplot/colour.h + ${PROJECT_SOURCE_DIR}/mplot/win_t.h + ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h + ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h + ${PROJECT_SOURCE_DIR}/mplot/Visual.h + ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h + ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h + ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h + ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h + ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h + ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h + ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h + ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/maths/sm/util + ${PROJECT_SOURCE_DIR}/maths/sm/base64 + ${PROJECT_SOURCE_DIR}/maths/sm/crc32 + ${PROJECT_SOURCE_DIR}/maths/sm/flags + ${PROJECT_SOURCE_DIR}/maths/sm/algo + ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/random + ${PROJECT_SOURCE_DIR}/maths/sm/vec + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/geometry + ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/vvec) +target_link_libraries(ellipsoid OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) + add_executable(vectorvis vectorvis.cpp) target_sources(vectorvis PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES diff --git a/examples/ellipsoid.cpp b/examples/ellipsoid.cpp index c651b9d3..f8ea6257 100644 --- a/examples/ellipsoid.cpp +++ b/examples/ellipsoid.cpp @@ -5,14 +5,15 @@ #include #include #include +#include -#include -#include +#include +import sm.mat; -#include -#include -#include -#include +import mplot.visual; +//import mplot.visualmodel; +//import mplot.colour; +import mplot.normalsvisual; // Quick visual that simply draws ellipsoid template @@ -39,7 +40,7 @@ int main() v.lightingEffects (true); auto pvm = std::make_unique> (sm::vec<>{}); - v.bindmodel (pvm); + pvm->set_parent (v.get_id()); pvm->finalize(); auto pvmp = v.addVisualModel (pvm); @@ -47,7 +48,7 @@ int main() if constexpr (show_normals) { // Create an associate normals model auto nrm = std::make_unique> (pvmp); - v.bindmodel (nrm); + nrm->set_parent (v.get_id()); nrm->finalize(); v.addVisualModel (nrm); } diff --git a/examples/rod_with_normals.cpp b/examples/rod_with_normals.cpp index b52bda30..63143d96 100644 --- a/examples/rod_with_normals.cpp +++ b/examples/rod_with_normals.cpp @@ -1,6 +1,7 @@ /* * Visualize a Rod */ +#include #include #include #include @@ -8,12 +9,10 @@ #include #include -#include - -#include -#include -#include -#include +import mplot.visual; +import mplot.colourmap; +import mplot.rodvisual; +import mplot.normalsvisual; int main() { @@ -34,13 +33,13 @@ int main() sm::vec start = { 0, 0, 0 }; sm::vec end = { 0.25, 0, 0 }; auto rvm = std::make_unique> (offset, start, end, 0.1f, colour1, colour1); - v.bindmodel (rvm); + rvm->set_parent (v.get_id()); rvm->use_oriented_tube = false; rvm->finalize(); auto rvmp1 = v.addVisualModel (rvm); auto nrm = std::make_unique> (rvmp1); - v.bindmodel (nrm); + nrm->set_parent (v.get_id()); nrm->finalize(); v.addVisualModel (nrm); @@ -49,13 +48,13 @@ int main() sm::vec end2 = { 0.2, 0.4, 0.6 }; // You can reuse the unique_ptr rvm, once you've transferred ownership with v.addVisualModel (rvm) rvm = std::make_unique>(offset, start2, end2, 0.05f, colour2); - v.bindmodel (rvm); + rvm->set_parent (v.get_id()); rvm->finalize(); auto rvmp2 = v.addVisualModel (rvm); // Create an associate normals model nrm = std::make_unique> (rvmp2); - v.bindmodel (nrm); + nrm->set_parent (v.get_id()); nrm->finalize(); v.addVisualModel (nrm); diff --git a/mplot/NormalsVisual.h b/mplot/NormalsVisual.h index c158b855..114f3dff 100644 --- a/mplot/NormalsVisual.h +++ b/mplot/NormalsVisual.h @@ -1,17 +1,22 @@ -#pragma once +module; /*! * \file Declares NormalsVisual to visualize the normals of another VisualModel */ +#include +#include #include -import sm.vec; +#include + +export module mplot.normalsvisual; + +export import mplot.visualmodel; +export import sm.vec; import sm.mat; import sm.flags; -#include -#include -namespace mplot +export namespace mplot { enum class normalsvisual_flags : uint32_t { diff --git a/mplot/VerticesVisual.h b/mplot/VerticesVisual.h index 28107690..4aaff866 100644 --- a/mplot/VerticesVisual.h +++ b/mplot/VerticesVisual.h @@ -1,4 +1,4 @@ -#pragma once +module; #include #include @@ -7,13 +7,15 @@ #include #include +export module mplot.verticesvisual; + import sm.vec; import sm.vvec; import sm.mat; -#include +export import mplot.visualmodel; -namespace mplot +export namespace mplot { /*! * Create a visual model directly from indices, vertices and normals, which might have been diff --git a/mplot/Visual.h b/mplot/Visual.h index dafee595..d6e31517 100644 --- a/mplot/Visual.h +++ b/mplot/Visual.h @@ -33,7 +33,7 @@ export import mplot.win_t; import mplot.visualresources; export import mplot.visualglfw; -import mplot.visualownable; +export import mplot.visualownable; export namespace mplot { diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index b316d550..4717b060 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -45,20 +45,20 @@ module; export module mplot.visualownable; -import mplot.visualmodel; -import mplot.win_t; -import mplot.visualcommon; +export import mplot.visualmodel; +export import mplot.win_t; +export import mplot.visualcommon; import mplot.visualresources; -import mplot.visualtextmodel; -import mplot.textgeometry; -import mplot.textfeatures; +export import mplot.visualtextmodel; +export import mplot.textgeometry; +export import mplot.textfeatures; import mplot.coordarrows; -import mplot.gl.version; +export import mplot.gl.version; import mplot.gl.util; import mplot.tools; -import sm.vec; -import sm.flags; +export import sm.vec; +export import sm.flags; import sm.quaternion; import sm.mat; diff --git a/mplot/compoundray/interop.h b/mplot/compoundray/interop.h index e8aec8c4..2714031c 100644 --- a/mplot/compoundray/interop.h +++ b/mplot/compoundray/interop.h @@ -4,7 +4,7 @@ * Author: Seb James * Date: June 2025 */ -#pragma once +module; // CompoundRay include files (*not* part of mathplot) #include @@ -12,16 +12,19 @@ #include #include +export module mplot.compoundray.interop; + // maths and mathplot includes import sm.vec; import sm.mat; -#include -#include + +import mplot.visual; +import mplot.verticesvisual; // scene exists at global scope in libEyeRenderer.so extern MulticamScene* scene; -namespace mplot::compoundray +export namespace mplot::compoundray { // Helper to convert sm::mat to Matrix4x4 sutil::Matrix4x4 mat44_to_Matrix4x4 (const sm::mat& m) diff --git a/mplot/fps/profiler.h b/mplot/fps/profiler.h index f0ca6e43..728be95a 100644 --- a/mplot/fps/profiler.h +++ b/mplot/fps/profiler.h @@ -5,7 +5,7 @@ * Author: Seb James * Date: 2024-2025 */ -#pragma once +module; #include #include @@ -13,7 +13,9 @@ #include #include -namespace mplot::fps +export module mplot.fps.profiler; + +export namespace mplot::fps { using namespace std::chrono; using sc = std::chrono::steady_clock; From 76778bd43ce6526553272a1b81bb6f6545bc6124 Mon Sep 17 00:00:00 2001 From: Seb James Date: Mon, 9 Mar 2026 10:29:24 +0000 Subject: [PATCH 038/106] Makes some colourmaps into modules to sidestep gcc-15 errors --- examples/CMakeLists.txt | 30 ++++++++++++++++++++++++++++++ mplot/ColourMap.h | 8 ++++---- mplot/ColourMap_Lists.h | 6 ++++-- mplot/VisualModel.h | 3 +-- mplot/colourmaps_cet.h | 7 ++++--- mplot/colourmaps_crameri.h | 5 +++-- 6 files changed, 46 insertions(+), 13 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7cfaa91c..0d6dc055 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -42,6 +42,9 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.h ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h ${PROJECT_SOURCE_DIR}/mplot/win_t.h ${PROJECT_SOURCE_DIR}/mplot/colour.h @@ -130,6 +133,9 @@ target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/maths/sm/crc32 @@ -169,6 +175,9 @@ target_sources(rod_with_normals PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_ ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/maths/sm/crc32 @@ -208,6 +217,9 @@ target_sources(ellipsoid PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_ ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/maths/sm/crc32 @@ -246,6 +258,9 @@ target_sources(vectorvis PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_ ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/maths/sm/crc32 @@ -288,6 +303,9 @@ target_sources(cray_eye PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_D ${PROJECT_SOURCE_DIR}/mplot/compoundray/EyeVisual.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/maths/sm/crc32 @@ -327,6 +345,9 @@ target_sources(graph1 PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h ${PROJECT_SOURCE_DIR}/mplot/graphing.h ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h ${PROJECT_SOURCE_DIR}/mplot/DatasetStyle.h @@ -373,6 +394,9 @@ target_sources(grid_simple PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURC ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.h ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 @@ -422,6 +446,9 @@ if(NOT APPLE) ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/maths/sm/crc32 @@ -478,6 +505,9 @@ if(ARMADILLO_FOUND) ${PROJECT_SOURCE_DIR}/mplot/DatasetStyle.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/maths/sm/crc32 diff --git a/mplot/ColourMap.h b/mplot/ColourMap.h index c4a07634..43e24e0e 100644 --- a/mplot/ColourMap.h +++ b/mplot/ColourMap.h @@ -1,10 +1,6 @@ module; -#include // Colour map tables from matplotlib -#include // Colour map tables from Fabio Crameri #include // William Lenthe's implementation of perceptually uniform colour maps -#include // Colour map tables from CET - #include #include #include @@ -14,6 +10,10 @@ module; export module mplot.colourmap; +export import :colourmaps_cet; // Colour map tables from CET +export import :colourmaps_crameri; // Colour map tables from Fabio Crameri +export import :colourmap_lists; // Colour map tables from matplotlib + import mplot.tools; import sm.vec; import sm.flags; diff --git a/mplot/ColourMap_Lists.h b/mplot/ColourMap_Lists.h index 0d330114..4426fc74 100644 --- a/mplot/ColourMap_Lists.h +++ b/mplot/ColourMap_Lists.h @@ -1,11 +1,13 @@ -#pragma once +module; #include +export module mplot.colourmap:colourmap_lists; + /*! * Listed colour maps, copied from _cm_listed.py */ -namespace mplot +export namespace mplot { /*! * Magma diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index 1b4d14e6..61c071c1 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -56,8 +56,7 @@ export import mplot.colour; import mplot.gl.util; import mplot.tools; -import :navmesh; -//#include +export import :navmesh; export namespace mplot { diff --git a/mplot/colourmaps_cet.h b/mplot/colourmaps_cet.h index 09524efc..f6191779 100644 --- a/mplot/colourmaps_cet.h +++ b/mplot/colourmaps_cet.h @@ -1,11 +1,12 @@ // CET Colour maps from https://colorcet.com/gallery.html // Converted into C++ lookup tables for mathplot by Seb James - -#pragma once +module; #include -namespace mplot::cet +export module mplot.colourmap:colourmaps_cet; + +export namespace mplot::cet { constexpr std::array, 256> cm_CET_C4s = {{ { 0.1020000f, 0.3900000f, 0.8970000f }, diff --git a/mplot/colourmaps_crameri.h b/mplot/colourmaps_crameri.h index 24b74c04..17f14572 100644 --- a/mplot/colourmaps_crameri.h +++ b/mplot/colourmaps_crameri.h @@ -1,10 +1,11 @@ // Scientific Colour Maps from Fabio Crameri (see https://zenodo.org/records/8409685) // Converted into C++ lookup tables for mathplot by Seb James - -#pragma once +module; #include +export module mplot.colourmap:colourmaps_crameri; + namespace mplot::crameri { constexpr std::array, 256> cm_lipari = {{ From b25cdf12ea0b19cbddb41cc8635605ce7bd04234 Mon Sep 17 00:00:00 2001 From: Seb James Date: Mon, 9 Mar 2026 13:19:45 +0000 Subject: [PATCH 039/106] Uses ifstream and fstream --- mplot/VisualOwnable.h | 1 + 1 file changed, 1 insertion(+) diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index 4717b060..c4cb7084 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -16,6 +16,7 @@ */ module; +#include #include #include #include From 54f394a1940ad31649b36062fa75379e9e6d5bca Mon Sep 17 00:00:00 2001 From: Seb James Date: Mon, 9 Mar 2026 14:43:23 +0000 Subject: [PATCH 040/106] cstdint for uint8_t --- mplot/VisualModel.h | 1 + 1 file changed, 1 insertion(+) diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index 61c071c1..6874d128 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -17,6 +17,7 @@ module; # include #endif +#include #include #include #include From 6cc37aaba6cb4d8a42bf228167de3c7d8a0a745b Mon Sep 17 00:00:00 2001 From: Seb James Date: Mon, 9 Mar 2026 14:47:41 +0000 Subject: [PATCH 041/106] Undoes a wrong change --- maths | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths b/maths index c2f7bf5f..a5f00d41 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit c2f7bf5f1fa087621d6fdedea98c0da59a1c397f +Subproject commit a5f00d419be0b6dbeaa317aa7caf75db32bb28c7 From 4c5d9d63a15246239baf29b27ac2b487c54a8288 Mon Sep 17 00:00:00 2001 From: Seb James Date: Mon, 9 Mar 2026 15:02:08 +0000 Subject: [PATCH 042/106] Changes for g++. location of nlohmann makes a difference. g++ didn't like tuple here. --- mplot/VisualOwnable.h | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index c4cb7084..fc4880c5 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -21,20 +21,23 @@ module; #include #include #include -#include +// clang was happy with a tuple: +//#include +// g++ generated an error with the tuple, so could use a pair: +#include #include #include #include #include +#include + #include #include #include #include -#include - #include // Use Lode Vandevenne's PNG encoder @@ -1739,7 +1742,8 @@ export namespace mplot if (fout.is_open()) { fout << "{\n"; } } - std::multimap, mplot::VisualModel*> > possible_centres; + //std::multimap, mplot::VisualModel*> > possible_centres; // tuple + std::multimap, mplot::VisualModel*> > possible_centres; // pair auto vmi = this->vm.begin(); while (vmi != this->vm.end()) { @@ -1766,7 +1770,8 @@ export namespace mplot if (tr_bb_centre[2] < 0.0f) { // Only if in front of viewer (z must be negative) // Perp. distance as key, value is tuple of BB centre and visualmodel pointer - possible_centres.insert ({ pdist, { tr_bb_centre, (*vmi).get() } }); + //possible_centres.insert ({ pdist, { tr_bb_centre, (*vmi).get() } }); // tuple + possible_centres.insert ({ pdist, std::make_pair (tr_bb_centre, (*vmi).get()) }); // pair } } ++vmi; @@ -1778,10 +1783,13 @@ export namespace mplot } if (!possible_centres.empty()) { - const auto [rcentre, vmptr] = possible_centres.begin()->second; - this->rotation_centre = rcentre; + //const auto [rcentre, vmptr] = possible_centres.begin()->second; // tuple + std::pair, mplot::VisualModel*> pr = possible_centres.begin()->second; // pair + // this->rotation_centre = rcentre; // tuple + this->rotation_centre = pr.first; // pair this->d_to_rotation_centre = this->rotation_centre.length(); - if (options.test (visual_options::highlightRotationVM)) { vmptr->show_bb (true); } + //if (options.test (visual_options::highlightRotationVM)) { vmptr->show_bb (true); } // tuple + if (options.test (visual_options::highlightRotationVM)) { pr.second->show_bb (true); } // pair } // else don't change rotation_centre } From e865b469f003ea8d5df5a788611a512ca4ee6735 Mon Sep 17 00:00:00 2001 From: Seb James Date: Mon, 9 Mar 2026 15:03:02 +0000 Subject: [PATCH 043/106] Modularizes geodesic visual --- examples/CMakeLists.txt | 49 ++++++++++++++++++++++++++++++++++++++++ examples/breadcrumbs.cpp | 2 +- examples/geodesic.cpp | 10 ++++---- mplot/GeodesicVisual.h | 19 ++++++++++------ 4 files changed, 66 insertions(+), 14 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 0d6dc055..a2b4d2e1 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -67,6 +67,8 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.h + ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.h + ${PROJECT_SOURCE_DIR}/mplot/compoundray/EyeVisual.h ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.h @@ -235,6 +237,52 @@ target_sources(ellipsoid PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_ ${PROJECT_SOURCE_DIR}/maths/sm/vvec) target_link_libraries(ellipsoid OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) +if(NOT APPLE) + add_executable(geodesic geodesic.cpp) + target_sources(geodesic PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES + ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/gl/version.h + ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h + ${PROJECT_SOURCE_DIR}/mplot/colour.h + ${PROJECT_SOURCE_DIR}/mplot/win_t.h + ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h + ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h + ${PROJECT_SOURCE_DIR}/mplot/Visual.h + ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h + ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h + ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h + ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h + ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h + ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h + ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h + ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.h + ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h + ${PROJECT_SOURCE_DIR}/maths/sm/scale + ${PROJECT_SOURCE_DIR}/maths/sm/util + ${PROJECT_SOURCE_DIR}/maths/sm/base64 + ${PROJECT_SOURCE_DIR}/maths/sm/crc32 + ${PROJECT_SOURCE_DIR}/maths/sm/flags + ${PROJECT_SOURCE_DIR}/maths/sm/algo + ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/random + ${PROJECT_SOURCE_DIR}/maths/sm/vec + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/geometry + ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/vvec) + target_link_libraries(geodesic OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) +endif() + add_executable(vectorvis vectorvis.cpp) target_sources(vectorvis PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES @@ -445,6 +493,7 @@ if(NOT APPLE) ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.h + ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h diff --git a/examples/breadcrumbs.cpp b/examples/breadcrumbs.cpp index 538b1167..61a62e65 100644 --- a/examples/breadcrumbs.cpp +++ b/examples/breadcrumbs.cpp @@ -16,7 +16,7 @@ import mplot.visual; import mplot.colourmap; import mplot.instancedscattervisual; -#include +import mplot.geodesicvisual; // Instanced rendering requires OpenGL 4.3 or higher (for the SSBO) constexpr int glver = mplot::gl::version_4_3; diff --git a/examples/geodesic.cpp b/examples/geodesic.cpp index 32ef325f..3a5395e0 100644 --- a/examples/geodesic.cpp +++ b/examples/geodesic.cpp @@ -3,17 +3,15 @@ */ #include +#include #include #include #include #include #include -#include - -#include -#include -#include +import mplot.visual; +import mplot.geodesicvisual; int main() { @@ -35,7 +33,7 @@ int main() for (int i = 0; i < imax; ++i) { auto cl = cm.convert (i / static_cast(imax - 1)); auto gv1 = std::make_unique> (offset + step * i, 0.9f); - v.bindmodel (gv1); + gv1->set_parent (v.get_id()); gv1->iterations = i; std::string lbl = std::string("iterations = ") + std::to_string(i); gv1->addLabel (lbl, {0, -1, 0}, mplot::TextFeatures(0.06f)); diff --git a/mplot/GeodesicVisual.h b/mplot/GeodesicVisual.h index 4d810304..d37d41d9 100644 --- a/mplot/GeodesicVisual.h +++ b/mplot/GeodesicVisual.h @@ -1,15 +1,20 @@ -#pragma once +module; #include -import sm.vec; -import sm.vvec; -import sm.scale; +#include + +export module mplot.geodesicvisual; + +export import sm.vec; +export import sm.vvec; +export import sm.scale; import sm.geometry; import sm.geometry_polyhedra; -import mplot.visualmodel; -import mplot.colourmap; -namespace mplot +export import mplot.visualmodel; +export import mplot.colourmap; + +export namespace mplot { /*! * This class creates the vertices for an geodesic polyhedron in a 3D scene. From b8e5a1e2ae5947ccedb9b586fef72b1e29d31c42 Mon Sep 17 00:00:00 2001 From: Seb James Date: Mon, 9 Mar 2026 16:02:51 +0000 Subject: [PATCH 044/106] fixes --- mplot/compoundray/interop.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mplot/compoundray/interop.h b/mplot/compoundray/interop.h index 2714031c..98a6ab78 100644 --- a/mplot/compoundray/interop.h +++ b/mplot/compoundray/interop.h @@ -14,8 +14,9 @@ module; export module mplot.compoundray.interop; -// maths and mathplot includes +// maths and mathplot imports import sm.vec; +import sm.vvec; import sm.mat; import mplot.visual; @@ -148,7 +149,7 @@ export namespace mplot::compoundray << norm.size() << " norms, " << colr.size() << " colours" << std::endl; } auto vertvm = std::make_unique> (tfm, ind, posn, norm, colr); - thevisual->bindmodel (vertvm); + vertvm->set_parent (thevisual->get_id()); vertvm->name = mymeshes[mi]->name; if (make_navmeshes == true) { vertvm->make_navmesh(); } vertvm->finalize(); From 91dd350a090209ae63c6f2079bf1924b1f8ab40a Mon Sep 17 00:00:00 2001 From: Seb James Date: Mon, 9 Mar 2026 16:03:05 +0000 Subject: [PATCH 045/106] Trivial --- mplot/keys.h | 1 - 1 file changed, 1 deletion(-) diff --git a/mplot/keys.h b/mplot/keys.h index 1b244673..15d48e18 100644 --- a/mplot/keys.h +++ b/mplot/keys.h @@ -163,7 +163,6 @@ namespace mplot static constexpr int release = 0; static constexpr int press = 1; static constexpr int repeat = 2; - }; // Mouse buttons. left is really 'primary' and right is 'secondary' because From 550b6a917045fc2cce3f2e08ce7abd7776ac371f Mon Sep 17 00:00:00 2001 From: Seb James Date: Mon, 9 Mar 2026 16:16:42 +0000 Subject: [PATCH 046/106] Latest maths --- maths | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths b/maths index a5f00d41..449d125b 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit a5f00d419be0b6dbeaa317aa7caf75db32bb28c7 +Subproject commit 449d125b77d81b54bad73620e85fe2412e5be8a1 From 904d7427120b3e7acd735834e249f1fafb6f4e6b Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 10 Mar 2026 11:55:46 +0000 Subject: [PATCH 047/106] Change wording a little --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8c3254f7..c8886684 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ [![Mentioned in Awesome C++](https://awesome.re/mentioned-badge.svg)](https://github.com/myd7349/awesome-cpp?tab=readme-ov-file#data-visualization) -**Header-only library code to visualize C++ numerical simulations using modern OpenGL.** +**Modular C++20 library code to visualize numerical simulations using modern OpenGL.** Mathplot is a library for drawing **3D data visualization** objects called `VisualModels`. @@ -33,12 +33,16 @@ This quick start shows dependency installation for Linux, because on this platfo ```bash # Install dependencies for building graph1.cpp and (almost) all the other examples (assuming Debian-like OS) -sudo apt install build-essential cmake git wget \ +sudo apt install build-essential cmake git wget ninja-build \ nlohmann-json3-dev librapidxml-dev \ freeglut3-dev libglu1-mesa-dev libxmu-dev libxi-dev \ - libglfw3-dev libfreetype-dev libarmadillo-dev libhdf5-dev clang-23 # yes, it's bleeding edge, no this won't work + libglfw3-dev libfreetype-dev libarmadillo-dev libhdf5-dev -git clone --recurse-submodules git@github.com:sebsjames/mathplot # Get your copy of the morphologica code +# Install a very up to date compiler +sudo apt install clang-23 clang-tools-23 # You can't apt install clang-23, as it's currently pre-release +sudo apt install gcc-16 # this won't work either, but hopefully gcc16 will compile mathplot + +git clone --recurse-submodules git@github.com:sebsjames/mathplot # Get your copy of the mathplot code cd mathplot mkdir build # Create a build directory cd build From c27b917a343f100d8b30fd62f0a3fb1079b06534 Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 10 Mar 2026 11:58:06 +0000 Subject: [PATCH 048/106] Re-word --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c8886684..6e74ab23 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ int main() mplot::Visual v(1024, 768, "Made with mplot::GraphVisual"); // Create a GraphVisual object (obtaining a unique_ptr to the object) with a spatial offset within the scene of 0,0,0 auto gv = std::make_unique> (sm::vec({0,0,0})); - // This mandatory line of boilerplate code sets the parent pointer in GraphVisual and binds some functions + // This mandatory line of boilerplate code sets the parent ID in GraphVisual gv->set_parent (v.get_id()); // Data for the x axis. A vvec is like std::vector, but with built-in maths methods sm::vvec x; From ac073045a38435a8be22b1640dc7356c3dc1559b Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 10 Mar 2026 12:23:17 +0000 Subject: [PATCH 049/106] Latest fixes in maths, plus debug reduction --- maths | 2 +- mplot/VisualModel.h | 1 - mplot/VisualOwnable.h | 2 -- mplot/VisualResources.h | 1 - 4 files changed, 1 insertion(+), 5 deletions(-) diff --git a/maths b/maths index 449d125b..ab518b4a 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit 449d125b77d81b54bad73620e85fe2412e5be8a1 +Subproject commit ab518b4a6c6ba6d8ea31468cba6d0f063172fec0 diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index 6874d128..501ebb21 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -105,7 +105,6 @@ export namespace mplot //! Common code to call after the vertices have been set up. GL has to have been initialised. void postVertexInit() { - std::cout << "postvertexinit...\n" << std::flush; if (this->parentVis == std::numeric_limits::max()) { throw std::runtime_error ("parentVis is unset"); } diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index fc4880c5..d7d01e4d 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -266,7 +266,6 @@ export namespace mplot unsigned int addVisualModelId (std::unique_ptr& model) { std::unique_ptr> vmp = std::move(model); - std::cout << "set parent on visualmodel to " << visual_id << std::endl; vmp->set_parent (this->visual_id); if (vmp->instanced()) { this->state.set (visual_state::haveInstanced, true); } this->vm.push_back (std::move(vmp)); @@ -282,7 +281,6 @@ export namespace mplot T* addVisualModel (std::unique_ptr& model) { std::unique_ptr> vmp = std::move(model); - std::cout << "set parent on visualmodel to " << visual_id << std::endl; vmp->set_parent (this->visual_id); if (vmp->instanced()) { this->state.set (visual_state::haveInstanced, true); } this->vm.push_back (std::move(vmp)); diff --git a/mplot/VisualResources.h b/mplot/VisualResources.h index fe4d2613..37696cd2 100644 --- a/mplot/VisualResources.h +++ b/mplot/VisualResources.h @@ -185,7 +185,6 @@ export namespace mplot this->visual_keyed_shaderprogs[visual_id] = {}; // initialized empty with 0s this->visual_keyed_windows[visual_id] = win; this->visual_keyed_instanced_needs_update[visual_id] = false; - std::cout << "Registered Visual ID " << visual_id << std::endl; return visual_id; } From ff245a951721acf03dae19207a1a8adc284824c2 Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 10 Mar 2026 13:03:03 +0000 Subject: [PATCH 050/106] Some type-based tweaks in maths --- maths | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths b/maths index ab518b4a..c03db2fd 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit ab518b4a6c6ba6d8ea31468cba6d0f063172fec0 +Subproject commit c03db2fd4492c0c2690db2a4ea0b08036392342d From 3f0ec9efbf3c0d4ea5e65402ab78d947540de44a Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 10 Mar 2026 14:11:34 +0000 Subject: [PATCH 051/106] place khrplatform.h in gl.h --- mplot/glad/gl.h | 315 ++++++++++++++++++++++++++++++++++++++- mplot/glad/khrplatform.h | 311 -------------------------------------- 2 files changed, 314 insertions(+), 312 deletions(-) delete mode 100644 mplot/glad/khrplatform.h diff --git a/mplot/glad/gl.h b/mplot/glad/gl.h index 390b8b1a..49400fcb 100644 --- a/mplot/glad/gl.h +++ b/mplot/glad/gl.h @@ -1986,7 +1986,320 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #define GL_ZOOM_Y 0x0D17 -#include +/* #include */ +#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_ */ +/* end include khrplatform.h inclusion */ + typedef unsigned int GLenum; typedef unsigned char GLboolean; typedef unsigned int GLbitfield; diff --git a/mplot/glad/khrplatform.h b/mplot/glad/khrplatform.h deleted file mode 100644 index 01646449..00000000 --- a/mplot/glad/khrplatform.h +++ /dev/null @@ -1,311 +0,0 @@ -#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_ */ From a1fbffe44dc2eb260eba107d85762ad94ce4e246 Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 10 Mar 2026 14:14:00 +0000 Subject: [PATCH 052/106] Colourbar visual, plus some tweaks to rod.cpp --- examples/rod.cpp | 4 ---- mplot/ColourBarVisual.h | 20 ++++++++++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/examples/rod.cpp b/examples/rod.cpp index ad17ccca..b43ca71e 100644 --- a/examples/rod.cpp +++ b/examples/rod.cpp @@ -27,15 +27,12 @@ int main() constexpr sm::vec colour1 = { 1.0, 0.0, 0.0 }; constexpr sm::vec colour2 = { 0.0, 0.9, 0.4 }; - std::cout << "creating first...\n" << std::flush; - sm::vec offset = { 0.0, 0.0, 0.0 }; sm::vec start = { 0, 0, 0 }; sm::vec end = { 0.25, 0, 0 }; std::unique_ptr> rvm = std::make_unique> (offset, start, end, 0.1f, colour1, colour1); rvm->set_parent (v.get_id()); // A bind model call. howeer, we could pass v.visual_id to the VisualModel constructor rvm->finalize(); - std::cout << "addVisualmodel...\n" << std::flush; v.addVisualModel (rvm); sm::vec start2 = { -0.1, 0.2, 0.6 }; @@ -44,7 +41,6 @@ int main() rvm = std::make_unique>(offset, start2, end2, 0.05f, colour2); rvm->set_parent (v.get_id()); rvm->finalize(); - std::cout << "addVisualmodel...\n" << std::flush; v.addVisualModel (rvm); v.keepOpen(); diff --git a/mplot/ColourBarVisual.h b/mplot/ColourBarVisual.h index bbf39905..020ceea9 100644 --- a/mplot/ColourBarVisual.h +++ b/mplot/ColourBarVisual.h @@ -1,19 +1,27 @@ /* * A colour bar visual */ +module; -#pragma once +#include +#include +#include +#include +#include +#include + +export module mplot.colourbarvisual; import sm.range; import sm.scale; import sm.vec; -#include -#include -#include -#include +export import mplot.visualmodel; +export import mplot.colourmap; +import mplot.graphing; +export import mplot.graphstyles; -namespace mplot +export namespace mplot { // Should our colourbar be horizontal or vertical? Horizontal bars always have // min->max from left to right. Vertical bars always have min->max from bottom to From c2696ecd5cc117a1643ab7e6a25aa149963b35ae Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 10 Mar 2026 14:14:47 +0000 Subject: [PATCH 053/106] Debug reduction --- mplot/RodVisual.h | 1 - 1 file changed, 1 deletion(-) diff --git a/mplot/RodVisual.h b/mplot/RodVisual.h index 8dc3bb70..435329b2 100644 --- a/mplot/RodVisual.h +++ b/mplot/RodVisual.h @@ -54,7 +54,6 @@ export namespace mplot //! Initialize vertex buffer objects and vertex array object. void initializeVertices() { - std::cout << "right one called\n"; this->vertexPositions.clear(); this->vertexNormals.clear(); this->vertexColors.clear(); From ceffbea8c98f8f6ceec9c35ac2d8274bf6192640 Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 10 Mar 2026 17:16:06 +0000 Subject: [PATCH 054/106] Modularize rhombovisual --- mplot/RhomboVisual.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/mplot/RhomboVisual.h b/mplot/RhomboVisual.h index 7f945749..992221a1 100644 --- a/mplot/RhomboVisual.h +++ b/mplot/RhomboVisual.h @@ -1,11 +1,16 @@ -#pragma once +module; #include -import sm.vec; -#include -#include +#include +#include -namespace mplot +export module mplot.rhombovisual; + +export import mplot.visualmodel; +export import mplot.colourmap; +export import sm.vec; + +export namespace mplot { //! This class creates the vertices for a rhombohedron template From 8a4f7988d2bdc888dd286487c73e85afb90ff973 Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 12 Mar 2026 10:44:55 +0000 Subject: [PATCH 055/106] Gets the hexgrid example working --- examples/CMakeLists.txt | 64 +++++++++++++- examples/hexgrid.cpp | 13 +-- maths | 2 +- mplot/HexGridVisual.h | 184 +++++++++++++++++----------------------- 4 files changed, 146 insertions(+), 117 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a2b4d2e1..204b065a 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -12,8 +12,11 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/maths/sm/quaternion ${PROJECT_SOURCE_DIR}/maths/sm/mat ${PROJECT_SOURCE_DIR}/maths/sm/hex + ${PROJECT_SOURCE_DIR}/maths/sm/hexgrid ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord + ${PROJECT_SOURCE_DIR}/maths/sm/binomial ${PROJECT_SOURCE_DIR}/maths/sm/bezcurve + ${PROJECT_SOURCE_DIR}/maths/sm/bezcurvepath ${PROJECT_SOURCE_DIR}/maths/sm/winder ${PROJECT_SOURCE_DIR}/maths/sm/bootstrap ${PROJECT_SOURCE_DIR}/maths/sm/grid @@ -73,6 +76,8 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.h + ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.h + PROPERTIES LANGUAGE CXX ) @@ -578,6 +583,62 @@ if(ARMADILLO_FOUND) endif(ARMADILLO_FOUND) endif (0) + add_executable(hexgrid hexgrid.cpp) + target_sources(hexgrid PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES + ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/gl/version.h + ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h + ${PROJECT_SOURCE_DIR}/mplot/colour.h + ${PROJECT_SOURCE_DIR}/mplot/win_t.h + ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h + ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h + ${PROJECT_SOURCE_DIR}/mplot/Visual.h + ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h + ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h + ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h + ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h + ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h + ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h + ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h + ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h + ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h + ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.h + ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.h + ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h + ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h + ${PROJECT_SOURCE_DIR}/maths/sm/util + ${PROJECT_SOURCE_DIR}/maths/sm/base64 + ${PROJECT_SOURCE_DIR}/maths/sm/crc32 + ${PROJECT_SOURCE_DIR}/maths/sm/flags + ${PROJECT_SOURCE_DIR}/maths/sm/algo + ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/random + ${PROJECT_SOURCE_DIR}/maths/sm/vec + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/geometry + ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra + ${PROJECT_SOURCE_DIR}/maths/sm/vvec + ${PROJECT_SOURCE_DIR}/maths/sm/scale + ${PROJECT_SOURCE_DIR}/maths/sm/centroid + ${PROJECT_SOURCE_DIR}/maths/sm/grid + ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord + ${PROJECT_SOURCE_DIR}/maths/sm/binomial + ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex + ${PROJECT_SOURCE_DIR}/maths/sm/bezcurve + ${PROJECT_SOURCE_DIR}/maths/sm/bezcurvepath + ${PROJECT_SOURCE_DIR}/maths/sm/hex + ${PROJECT_SOURCE_DIR}/maths/sm/hexgrid + + ) + target_link_libraries(hexgrid OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) + if(0) # During development # @@ -641,9 +702,6 @@ if(ARMADILLO_FOUND) endif() endif() - add_executable(hexgrid hexgrid.cpp) - target_link_libraries(hexgrid OpenGL::GL glfw Freetype::Freetype) - add_executable(unicode_coordaxes unicode_coordaxes.cpp) target_link_libraries(unicode_coordaxes OpenGL::GL glfw Freetype::Freetype) diff --git a/examples/hexgrid.cpp b/examples/hexgrid.cpp index 223a1c10..ee47a7c8 100644 --- a/examples/hexgrid.cpp +++ b/examples/hexgrid.cpp @@ -3,15 +3,16 @@ */ #include +#include #include #include -#include -#include +import sm.vec; +import sm.hexgrid; -#include -#include -#include +import mplot.visual; +import mplot.visualdatamodel; +import mplot.hexgridvisual; int main() { @@ -48,7 +49,7 @@ int main() // Add a HexGridVisual to display the HexGrid within the sm::Visual scene sm::vec offset = { 0.0f, -0.05f, 0.0f }; auto hgv = std::make_unique>(&hg, offset); - v.bindmodel (hgv); + hgv->set_parent (v.get_id()); hgv->wireframe (true); hgv->cm.setType (mplot::ColourMapType::Ice); hgv->setScalarData (&data); diff --git a/maths b/maths index c03db2fd..0d93dde3 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit c03db2fd4492c0c2690db2a4ea0b08036392342d +Subproject commit 0d93dde36be8c9a490a3ac4c6ca24b16b667939f diff --git a/mplot/HexGridVisual.h b/mplot/HexGridVisual.h index 8d7270aa..f5cf09b6 100644 --- a/mplot/HexGridVisual.h +++ b/mplot/HexGridVisual.h @@ -1,55 +1,25 @@ -#pragma once +module; +#include +#include #include #include #include +#include + +export module mplot.hexgridvisual; + import sm.vec; import sm.vvec; -#include +import sm.hexgrid; import sm.scale; -import mplot.gl.version; +export import mplot.gl.version; +export import mplot.colourmap; import mplot.tools; import mplot.visualdatamodel; -import mplot.colourmap; - -/* - * Macros for testing neighbours. The step along for neighbours on the - * rows above/below is given by: - * - * Dest | step - * ---------------------- - * NNE | +rowlen - * NNW | +rowlen - 1 - * NSW | -rowlen - * NSE | -rowlen + 1 - */ -#define NE(hi) (this->hg->d_ne[hi]) -#define HAS_NE(hi) (this->hg->d_ne[hi] == -1 ? false : true) - -#define NW(hi) (this->hg->d_nw[hi]) -#define HAS_NW(hi) (this->hg->d_nw[hi] == -1 ? false : true) - -#define NNE(hi) (this->hg->d_nne[hi]) -#define HAS_NNE(hi) (this->hg->d_nne[hi] == -1 ? false : true) - -#define NNW(hi) (this->hg->d_nnw[hi]) -#define HAS_NNW(hi) (this->hg->d_nnw[hi] == -1 ? false : true) - -#define NSE(hi) (this->hg->d_nse[hi]) -#define HAS_NSE(hi) (this->hg->d_nse[hi] == -1 ? false : true) - -#define NSW(hi) (this->hg->d_nsw[hi]) -#define HAS_NSW(hi) (this->hg->d_nsw[hi] == -1 ? false : true) - -#define IF_HAS_NE(hi, yesval, noval) (HAS_NE(hi) ? yesval : noval) -#define IF_HAS_NNE(hi, yesval, noval) (HAS_NNE(hi) ? yesval : noval) -#define IF_HAS_NNW(hi, yesval, noval) (HAS_NNW(hi) ? yesval : noval) -#define IF_HAS_NW(hi, yesval, noval) (HAS_NW(hi) ? yesval : noval) -#define IF_HAS_NSW(hi, yesval, noval) (HAS_NSW(hi) ? yesval : noval) -#define IF_HAS_NSE(hi, yesval, noval) (HAS_NSE(hi) ? yesval : noval) - -namespace mplot + +export namespace mplot { enum class HexVisMode { @@ -60,7 +30,7 @@ namespace mplot //! The template argument T is the type of the data which this HexGridVisual //! will visualize. - template + template class HexGridVisual : public VisualDataModel { public: @@ -76,11 +46,11 @@ namespace mplot } //! Hexes to mark out. There are hex iterators, that I can do if (markedHexes.count(hi)) {} - std::set markedHexes; + std::set markedHexes; //! Mark a hex at location r,g,b=0 - it should be outlined with a ring, or //! something, so that it is visible. - void markHex (unsigned int hi) { this->markedHexes.insert(hi); } + void markHex (uint32_t hi) { this->markedHexes.insert(hi); } //! Zoom factor float zoom = 1.0f; @@ -127,7 +97,7 @@ namespace mplot // This locally defined reinit function knows that we don't want to clear vertexPositions/vertexNormals void reinit_on_update() { - if (this->setContext != nullptr) { this->setContext (this->parentVis); } + mplot::VisualResources::i().setContext (this->parentVis); // No need to set idx to 0 on an update, or clear/empty vertex/indices containers this->initializeVertices (true); // true for 'update' not 'initial build' this->reinit_buffers(); // could potentially be 'reinit_position_color_buffers_only()' @@ -162,7 +132,7 @@ namespace mplot */ void initializeVerticesTris (const bool update) { - unsigned int nhex = this->hg->num(); + uint32_t nhex = this->hg->num(); this->setupScaling(); @@ -175,7 +145,7 @@ namespace mplot this->indices.reserve (6u * nhex); } - for (unsigned int hi = 0; hi < nhex; ++hi) { + for (uint32_t hi = 0; hi < nhex; ++hi) { std::array clr = this->setColour (hi); // If dataCoords has been populated, use these for hex positions, allowing for // mapping of the 2D hexgrid onto a 3D manifold. @@ -213,21 +183,21 @@ namespace mplot // Only needs to happen *on init*. On update, this will not change :) if (update == false) { std::size_t ind_sz = 0; - for (unsigned int hi = 0; hi < nhex; ++hi) { - if (HAS_NNE(hi) && HAS_NE(hi)) { + for (uint32_t hi = 0; hi < nhex; ++hi) { + if (this->hg->has_nne(hi) && this->hg->has_ne(hi)) { //std::cout << "1st triangle " << hi << "->" << NNE(hi) << "->" << NE(hi) << std::endl; this->indices.resize (ind_sz + 3); this->indices[ind_sz++] = hi; - this->indices[ind_sz++] = NNE(hi); - this->indices[ind_sz++] = NE(hi); + this->indices[ind_sz++] = this->hg->nne(hi); + this->indices[ind_sz++] = this->hg->ne(hi); } - if (HAS_NW(hi) && HAS_NSW(hi)) { + if (this->hg->has_nw(hi) && this->hg->has_nsw(hi)) { //std::cout << "2nd triangle " << hi << "->" << NW(hi) << "->" << NSW(hi) << std::endl; this->indices.resize (ind_sz + 3); this->indices[ind_sz++] = hi; - this->indices[ind_sz++] = NW(hi); - this->indices[ind_sz++] = NSW(hi); + this->indices[ind_sz++] = this->hg->nw(hi); + this->indices[ind_sz++] = this->hg->nsw(hi); } } this->idx = nhex; @@ -264,7 +234,7 @@ namespace mplot float vne = this->hg->getVtoNE(); float lr = this->hg->getLR(); - unsigned int nhex = this->hg->num(); + uint32_t nhex = this->hg->num(); this->setupScaling(); @@ -293,19 +263,19 @@ namespace mplot sm::vec coordNSW = coordC; sm::vec coordNSE = coordC; - for (unsigned int hi = 0; hi < nhex; ++hi) { + for (uint32_t hi = 0; hi < nhex; ++hi) { if (this->dataCoords == nullptr) { _x = this->hg->d_x[hi]; _y = this->hg->d_y[hi]; // Use the linear scaled copy of the data, dcopy. datumC = this->dcopy[hi]; // '_z' - datumNE = HAS_NE(hi) ? this->dcopy[NE(hi)] : datumC; // datum Neighbour East - datumNNE = HAS_NNE(hi) ? this->dcopy[NNE(hi)] : datumC; // datum Neighbour North East - datumNNW = HAS_NNW(hi) ? this->dcopy[NNW(hi)] : datumC; // etc - datumNW = HAS_NW(hi) ? this->dcopy[NW(hi)] : datumC; - datumNSW = HAS_NSW(hi) ? this->dcopy[NSW(hi)] : datumC; - datumNSE = HAS_NSE(hi) ? this->dcopy[NSE(hi)] : datumC; + datumNE = this->hg->has_ne(hi) ? this->dcopy[this->hg->ne(hi)] : datumC; // datum Neighbour East + datumNNE = this->hg->has_nne(hi) ? this->dcopy[this->hg->nne(hi)] : datumC; // datum Neighbour North East + datumNNW = this->hg->has_nnw(hi) ? this->dcopy[this->hg->nnw(hi)] : datumC; // etc + datumNW = this->hg->has_nw(hi) ? this->dcopy[this->hg->nw(hi)] : datumC; + datumNSW = this->hg->has_nsw(hi) ? this->dcopy[this->hg->nsw(hi)] : datumC; + datumNSE = this->hg->has_nse(hi) ? this->dcopy[this->hg->nse(hi)] : datumC; } else { // Get coordinates from dataCoords _x = (*this->dataCoords)[hi][0]; @@ -313,12 +283,12 @@ namespace mplot datumC = (*this->dataCoords)[hi][2]; coordC = (*this->dataCoords)[hi]; - coordNE = HAS_NE(hi) ? (*this->dataCoords)[NE(hi)] : (*this->dataCoords)[hi]; // datum Neighbour East - coordNNE = HAS_NNE(hi) ? (*this->dataCoords)[NNE(hi)] : (*this->dataCoords)[hi]; // datum Neighbour North East - coordNNW = HAS_NNW(hi) ? (*this->dataCoords)[NNW(hi)] : (*this->dataCoords)[hi]; // etc - coordNW = HAS_NW(hi) ? (*this->dataCoords)[NW(hi)] : (*this->dataCoords)[hi]; - coordNSW = HAS_NSW(hi) ? (*this->dataCoords)[NSW(hi)] : (*this->dataCoords)[hi]; - coordNSE = HAS_NSE(hi) ? (*this->dataCoords)[NSE(hi)] : (*this->dataCoords)[hi]; + coordNE = this->hg->has_ne(hi) ? (*this->dataCoords)[this->hg->ne(hi)] : (*this->dataCoords)[hi]; // datum Neighbour East + coordNNE = this->hg->has_nne(hi) ? (*this->dataCoords)[this->hg->nne(hi)] : (*this->dataCoords)[hi]; // datum Neighbour North East + coordNNW = this->hg->has_nnw(hi) ? (*this->dataCoords)[this->hg->nnw(hi)] : (*this->dataCoords)[hi]; // etc + coordNW = this->hg->has_nw(hi) ? (*this->dataCoords)[this->hg->nw(hi)] : (*this->dataCoords)[hi]; + coordNSW = this->hg->has_nsw(hi) ? (*this->dataCoords)[this->hg->nsw(hi)] : (*this->dataCoords)[hi]; + coordNSE = this->hg->has_nse(hi) ? (*this->dataCoords)[this->hg->nse(hi)] : (*this->dataCoords)[hi]; datumNE = coordNE[2]; datumNNE = coordNNE[2]; @@ -347,11 +317,11 @@ namespace mplot // NE vertex if (this->dataCoords == nullptr) { - if (HAS_NNE(hi) && HAS_NE(hi)) { + if (this->hg->has_nne(hi) && this->hg->has_ne(hi)) { // Compute mean of this->data[hi] and NE and E hexes datum = third * (datumC + datumNNE + datumNE); - } else if (HAS_NNE(hi) || HAS_NE(hi)) { - if (HAS_NNE(hi)) { + } else if (this->hg->has_nne(hi) || this->hg->has_ne(hi)) { + if (this->hg->has_nne(hi)) { datum = half * (datumC + datumNNE); } else { datum = half * (datumC + datumNE); @@ -362,11 +332,11 @@ namespace mplot vtx_1 = { (_x+sr), (_y+vne), datum }; } else { // Similar logic, but for the coordinate, not just the data value - if (HAS_NNE(hi) && HAS_NE(hi)) { + if (this->hg->has_nne(hi) && this->hg->has_ne(hi)) { // Compute mean of coordC and NE and E hexes vtx_1 = third * (coordC + coordNNE + coordNE); - } else if (HAS_NNE(hi) || HAS_NE(hi)) { - if (HAS_NNE(hi)) { + } else if (this->hg->has_nne(hi) || this->hg->has_ne(hi)) { + if (this->hg->has_nne(hi)) { vtx_1 = half * (coordC + coordNNE); } else { vtx_1 = half * (coordC + coordNE); @@ -380,10 +350,10 @@ namespace mplot // SE vertex if (this->dataCoords == nullptr) { - if (HAS_NE(hi) && HAS_NSE(hi)) { + if (this->hg->has_ne(hi) && this->hg->has_nse(hi)) { datum = third * (datumC + datumNE + datumNSE); - } else if (HAS_NE(hi) || HAS_NSE(hi)) { - if (HAS_NE(hi)) { + } else if (this->hg->has_ne(hi) || this->hg->has_nse(hi)) { + if (this->hg->has_ne(hi)) { datum = half * (datumC + datumNE); } else { datum = half * (datumC + datumNSE); @@ -393,10 +363,10 @@ namespace mplot } vtx_2 = { (_x+sr), (_y-vne), datum }; } else { - if (HAS_NE(hi) && HAS_NSE(hi)) { + if (this->hg->has_ne(hi) && this->hg->has_nse(hi)) { vtx_2 = third * (coordC + coordNE + coordNSE); - } else if (HAS_NE(hi) || HAS_NSE(hi)) { - if (HAS_NE(hi)) { + } else if (this->hg->has_ne(hi) || this->hg->has_nse(hi)) { + if (this->hg->has_ne(hi)) { vtx_2 = half * (coordC + coordNE); } else { vtx_2 = half * (coordC + coordNSE); @@ -410,10 +380,10 @@ namespace mplot // S if (this->dataCoords == nullptr) { - if (HAS_NSE(hi) && HAS_NSW(hi)) { + if (this->hg->has_nse(hi) && this->hg->has_nsw(hi)) { datum = third * (datumC + datumNSE + datumNSW); - } else if (HAS_NSE(hi) || HAS_NSW(hi)) { - if (HAS_NSE(hi)) { + } else if (this->hg->has_nse(hi) || this->hg->has_nsw(hi)) { + if (this->hg->has_nse(hi)) { datum = half * (datumC + datumNSE); } else { datum = half * (datumC + datumNSW); @@ -423,10 +393,10 @@ namespace mplot } vtx_tmp = { _x, (_y-lr), datum }; } else { - if (HAS_NSE(hi) && HAS_NSW(hi)) { + if (this->hg->has_nse(hi) && this->hg->has_nsw(hi)) { vtx_tmp = third * (coordC + coordNSE + coordNSW); - } else if (HAS_NSE(hi) || HAS_NSW(hi)) { - if (HAS_NSE(hi)) { + } else if (this->hg->has_nse(hi) || this->hg->has_nsw(hi)) { + if (this->hg->has_nse(hi)) { vtx_tmp = half * (coordC + coordNSE); } else { vtx_tmp = half * (coordC + coordNSW); @@ -439,10 +409,10 @@ namespace mplot // SW if (this->dataCoords == nullptr) { - if (HAS_NW(hi) && HAS_NSW(hi)) { + if (this->hg->has_nw(hi) && this->hg->has_nsw(hi)) { datum = third * (datumC + datumNW + datumNSW); - } else if (HAS_NW(hi) || HAS_NSW(hi)) { - if (HAS_NW(hi)) { + } else if (this->hg->has_nw(hi) || this->hg->has_nsw(hi)) { + if (this->hg->has_nw(hi)) { datum = half * (datumC + datumNW); } else { datum = half * (datumC + datumNSW); @@ -452,10 +422,10 @@ namespace mplot } vtx_tmp = { (_x-sr), (_y-vne), datum }; } else { - if (HAS_NW(hi) && HAS_NSW(hi)) { + if (this->hg->has_nw(hi) && this->hg->has_nsw(hi)) { vtx_tmp = third * (coordC + coordNW + coordNSW); - } else if (HAS_NW(hi) || HAS_NSW(hi)) { - if (HAS_NW(hi)) { + } else if (this->hg->has_nw(hi) || this->hg->has_nsw(hi)) { + if (this->hg->has_nw(hi)) { vtx_tmp = half * (coordC + coordNW); } else { vtx_tmp = half * (coordC + coordNSW); @@ -468,10 +438,10 @@ namespace mplot // NW if (this->dataCoords == nullptr) { - if (HAS_NNW(hi) && HAS_NW(hi)) { + if (this->hg->has_nnw(hi) && this->hg->has_nw(hi)) { datum = third * (datumC + datumNNW + datumNW); - } else if (HAS_NNW(hi) || HAS_NW(hi)) { - if (HAS_NNW(hi)) { + } else if (this->hg->has_nnw(hi) || this->hg->has_nw(hi)) { + if (this->hg->has_nnw(hi)) { datum = half * (datumC + datumNNW); } else { datum = half * (datumC + datumNW); @@ -481,10 +451,10 @@ namespace mplot } vtx_tmp = { (_x-sr), (_y+vne), datum }; } else { - if (HAS_NNW(hi) && HAS_NW(hi)) { + if (this->hg->has_nnw(hi) && this->hg->has_nw(hi)) { vtx_tmp = third * (coordC + coordNNW + coordNW); - } else if (HAS_NNW(hi) || HAS_NW(hi)) { - if (HAS_NNW(hi)) { + } else if (this->hg->has_nnw(hi) || this->hg->has_nw(hi)) { + if (this->hg->has_nnw(hi)) { vtx_tmp = half * (coordC + coordNNW); } else { vtx_tmp = half * (coordC + coordNW); @@ -497,10 +467,10 @@ namespace mplot // N if (this->dataCoords == nullptr) { - if (HAS_NNW(hi) && HAS_NNE(hi)) { + if (this->hg->has_nnw(hi) && this->hg->has_nne(hi)) { datum = third * (datumC + datumNNW + datumNNE); - } else if (HAS_NNW(hi) || HAS_NNE(hi)) { - if (HAS_NNW(hi)) { + } else if (this->hg->has_nnw(hi) || this->hg->has_nne(hi)) { + if (this->hg->has_nnw(hi)) { datum = half * (datumC + datumNNW); } else { datum = half * (datumC + datumNNE); @@ -510,10 +480,10 @@ namespace mplot } vtx_tmp = { _x, (_y+lr), datum }; } else { - if (HAS_NNW(hi) && HAS_NNE(hi)) { + if (this->hg->has_nnw(hi) && this->hg->has_nne(hi)) { vtx_tmp = third * (coordC + coordNNW + coordNNE); - } else if (HAS_NNW(hi) || HAS_NNE(hi)) { - if (HAS_NNW(hi)) { + } else if (this->hg->has_nnw(hi) || this->hg->has_nne(hi)) { + if (this->hg->has_nnw(hi)) { vtx_tmp = half * (coordC + coordNNW); } else { vtx_tmp = half * (coordC + coordNNE); @@ -613,10 +583,10 @@ namespace mplot float sr = this->hg->getSR(); float vne = this->hg->getVtoNE(); float lr = this->hg->getLR(); - unsigned int nhex = this->hg->num(); + uint32_t nhex = this->hg->num(); sm::vec vtx_0, vtx_1, vtx_2; - for (unsigned int hi = 0; hi < nhex; ++hi) { + for (uint32_t hi = 0; hi < nhex; ++hi) { // z position is always 0 float datum = 0.0f; From e4a2ede2a87060e2ab12f99b93a6bf030b0ff737 Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 12 Mar 2026 11:23:41 +0000 Subject: [PATCH 056/106] Makes showcase work --- examples/CMakeLists.txt | 63 +++++++--- examples/showcase.cpp | 42 ++++--- mplot/ScatterVisual.h | 13 ++- mplot/TriaxesVisual.h | 20 +++- mplot/VisualOwnable.h | 12 +- mplot/VisualTextModel.h | 5 +- mplot/loadpng.h | 43 ++++--- mplot/unicode.h | 249 ++++++++++++++++++++-------------------- 8 files changed, 249 insertions(+), 198 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 204b065a..dbd8e807 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -31,6 +31,7 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/maths/sm/crc32 + ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h ${PROJECT_SOURCE_DIR}/mplot/Visual.h ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h @@ -52,6 +53,8 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/win_t.h ${PROJECT_SOURCE_DIR}/mplot/colour.h ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/unicode.h + ${PROJECT_SOURCE_DIR}/mplot/loadpng.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h @@ -78,6 +81,10 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.h + ${PROJECT_SOURCE_DIR}/mplot/TriaxesVisual.h + + ${PROJECT_SOURCE_DIR}/mplot/ScatterVisual.h + PROPERTIES LANGUAGE CXX ) @@ -85,6 +92,8 @@ add_executable(helloworld helloworld.cpp) target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/unicode.h + ${PROJECT_SOURCE_DIR}/mplot/loadpng.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h ${PROJECT_SOURCE_DIR}/mplot/colour.h @@ -121,6 +130,8 @@ add_executable(rod rod.cpp) target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/unicode.h + ${PROJECT_SOURCE_DIR}/mplot/loadpng.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h ${PROJECT_SOURCE_DIR}/mplot/colour.h @@ -162,6 +173,8 @@ add_executable(rod_with_normals rod_with_normals.cpp) target_sources(rod_with_normals PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/unicode.h + ${PROJECT_SOURCE_DIR}/mplot/loadpng.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h ${PROJECT_SOURCE_DIR}/mplot/colour.h @@ -204,6 +217,8 @@ add_executable(ellipsoid ellipsoid.cpp) target_sources(ellipsoid PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/unicode.h + ${PROJECT_SOURCE_DIR}/mplot/loadpng.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h ${PROJECT_SOURCE_DIR}/mplot/colour.h @@ -247,6 +262,8 @@ if(NOT APPLE) target_sources(geodesic PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/unicode.h + ${PROJECT_SOURCE_DIR}/mplot/loadpng.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h ${PROJECT_SOURCE_DIR}/mplot/colour.h @@ -292,6 +309,8 @@ add_executable(vectorvis vectorvis.cpp) target_sources(vectorvis PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/unicode.h + ${PROJECT_SOURCE_DIR}/mplot/loadpng.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h ${PROJECT_SOURCE_DIR}/mplot/colour.h @@ -333,6 +352,8 @@ add_executable(cray_eye cray_eye.cpp) target_sources(cray_eye PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/unicode.h + ${PROJECT_SOURCE_DIR}/mplot/loadpng.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h ${PROJECT_SOURCE_DIR}/mplot/colour.h @@ -380,6 +401,8 @@ add_executable(graph1 graph1.cpp) target_sources(graph1 PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/unicode.h + ${PROJECT_SOURCE_DIR}/mplot/loadpng.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h ${PROJECT_SOURCE_DIR}/mplot/colour.h @@ -428,6 +451,8 @@ add_executable(grid_simple grid_simple.cpp) target_sources(grid_simple PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/unicode.h + ${PROJECT_SOURCE_DIR}/mplot/loadpng.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h ${PROJECT_SOURCE_DIR}/mplot/colour.h @@ -479,6 +504,8 @@ if(NOT APPLE) target_sources(breadcrumbs PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/unicode.h + ${PROJECT_SOURCE_DIR}/mplot/loadpng.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h ${PROJECT_SOURCE_DIR}/mplot/colour.h @@ -523,16 +550,12 @@ if(NOT APPLE) target_link_libraries(breadcrumbs OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) endif() -# -# Any example that uses sm::hexgrid or sm::cartgrid requires -# libarmadillo (because the classes use sm::BezCurve). -# -if(0) -if(ARMADILLO_FOUND) - add_executable(showcase showcase.cpp) - target_sources(showcase PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} +add_executable(showcase showcase.cpp) +target_sources(showcase PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/unicode.h + ${PROJECT_SOURCE_DIR}/mplot/loadpng.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h ${PROJECT_SOURCE_DIR}/mplot/colour.h @@ -551,17 +574,20 @@ if(ARMADILLO_FOUND) ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.h ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h - - ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h - ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h ${PROJECT_SOURCE_DIR}/mplot/graphing.h ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h ${PROJECT_SOURCE_DIR}/mplot/DatasetStyle.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h + + ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.h + ${PROJECT_SOURCE_DIR}/mplot/TriaxesVisual.h + ${PROJECT_SOURCE_DIR}/mplot/ScatterVisual.h + ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h + ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h + ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/maths/sm/crc32 @@ -571,6 +597,7 @@ if(ARMADILLO_FOUND) ${PROJECT_SOURCE_DIR}/maths/sm/random ${PROJECT_SOURCE_DIR}/maths/sm/vec ${PROJECT_SOURCE_DIR}/maths/sm/quaternion + ${PROJECT_SOURCE_DIR}/maths/sm/histo ${PROJECT_SOURCE_DIR}/maths/sm/mat ${PROJECT_SOURCE_DIR}/maths/sm/geometry ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra @@ -578,15 +605,22 @@ if(ARMADILLO_FOUND) ${PROJECT_SOURCE_DIR}/maths/sm/scale ${PROJECT_SOURCE_DIR}/maths/sm/centroid ${PROJECT_SOURCE_DIR}/maths/sm/grid + ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord + ${PROJECT_SOURCE_DIR}/maths/sm/binomial + ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex + ${PROJECT_SOURCE_DIR}/maths/sm/bezcurve + ${PROJECT_SOURCE_DIR}/maths/sm/bezcurvepath + ${PROJECT_SOURCE_DIR}/maths/sm/hex + ${PROJECT_SOURCE_DIR}/maths/sm/hexgrid ) target_link_libraries(showcase OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) -endif(ARMADILLO_FOUND) -endif (0) add_executable(hexgrid hexgrid.cpp) target_sources(hexgrid PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/unicode.h + ${PROJECT_SOURCE_DIR}/mplot/loadpng.h ${PROJECT_SOURCE_DIR}/mplot/gl/version.h ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h ${PROJECT_SOURCE_DIR}/mplot/colour.h @@ -635,7 +669,6 @@ endif (0) ${PROJECT_SOURCE_DIR}/maths/sm/bezcurvepath ${PROJECT_SOURCE_DIR}/maths/sm/hex ${PROJECT_SOURCE_DIR}/maths/sm/hexgrid - ) target_link_libraries(hexgrid OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) diff --git a/examples/showcase.cpp b/examples/showcase.cpp index 50f965cf..e43b04d5 100644 --- a/examples/showcase.cpp +++ b/examples/showcase.cpp @@ -1,18 +1,22 @@ // A showcase of different visual models +#include +#include +#include +#include +#include import sm.vvec; import sm.grid; +import sm.hexgrid; -#include -#include - -#include +import mplot.loadpng; +import mplot.unicode; import mplot.visual; -#include -#include -#include -#include -#include +import mplot.graphvisual; +import mplot.hexgridvisual; +import mplot.gridvisual; +import mplot.triaxesvisual; +import mplot.scattervisual; // A simple Izhikevich neuron model class used below struct izhi @@ -94,7 +98,7 @@ int main() */ { auto gv1 = std::make_unique> (sm::vec({0,1,0})); - v.bindmodel (gv1); + gv1->set_parent (v.get_id()); gv1->axisstyle = mplot::axisstyle::twinax; gv1->setsize (1.6, 1.6); sm::vvec x; @@ -122,7 +126,7 @@ int main() data[ri] = 0.05f + 0.15f*std::sin(10.0f*hg.d_x[ri]) * std::sin(1.8f*hg.d_y[ri]) ; // Range 0->1 } auto hgv = std::make_unique>(&hg, sm::vec({-2,-0.5,0})); - v.bindmodel (hgv); + hgv->set_parent (v.get_id()); hgv->setScalarData (&data); hgv->cm.setType (mplot::ColourMapType::Inferno); hgv->hexVisMode = mplot::HexVisMode::HexInterp; // Or mplot::HexVisMode::Triangles for a smoother surface plot @@ -149,7 +153,7 @@ int main() } sm::vec offset = { -1.1f, -1.0f, 0.0f }; auto gv = std::make_unique>(&grid, offset); - v.bindmodel (gv); + gv->set_parent (v.get_id()); gv->gridVisMode = mplot::GridVisMode::Columns; gv->setScalarData (&data); gv->cm.setType (mplot::ColourMapType::Twilight); @@ -173,7 +177,7 @@ int main() // Now visualise with a GridVisual auto gv2 = std::make_unique>(&g2, sm::vec({0.2,-0.5,0})); - v.bindmodel (gv2); + gv2->set_parent (v.get_id()); gv2->gridVisMode = mplot::GridVisMode::Pixels; gv2->setScalarData (&image_data); gv2->cm.setType (mplot::ColourMapType::GreyscaleInv); @@ -182,7 +186,7 @@ int main() gv2->finalize(); v.addVisualModel (gv2); auto gv3 = std::make_unique>(&g2, sm::vec({0.2,-1,0})); - v.bindmodel (gv3); + gv3->set_parent (v.get_id()); gv3->gridVisMode = mplot::GridVisMode::Columns; gv3->interpolate_colour_sides (true); gv3->setScalarData (&image_data); @@ -203,7 +207,7 @@ int main() // First the Triaxes: auto scat_offs = sm::vec({-4,-1.0,0}); auto tav = std::make_unique>(scat_offs); - v.bindmodel (tav); + tav->set_parent (v.get_id()); tav->axisstyle = mplot::axisstyle::L; // Specify axes min and max with a min and max vector // x y z @@ -217,7 +221,7 @@ int main() v.addVisualModel (tav); // Second the scatter vis: auto sv = std::make_unique> (scat_offs); - v.bindmodel (sv); + sv->set_parent (v.get_id()); sm::vvec> points(20*20); sm::vvec data(20*20); sv->setDataCoords (&points); @@ -281,7 +285,7 @@ int main() // Graph membrane voltage vs. time sm::vec izoff = {-4, 1, 0}; auto gv = std::make_unique> (sm::vec({0,0,0})+izoff); - v.bindmodel (gv); + gv->set_parent (v.get_id()); gv->twodimensional (twodee); gv->setsize (1,0.8); gv->xlabel = "t"; @@ -295,7 +299,7 @@ int main() // Graph u(t) auto gu = std::make_unique> (sm::vec({0,1.1,0})+izoff); - v.bindmodel (gu); + gu->set_parent (v.get_id()); gu->twodimensional (twodee); gu->setsize (1,0.5); gu->xlabel = "t"; @@ -312,7 +316,7 @@ int main() // Graph nullclines, u vs v and vector field ds.showlines = false; auto gp = std::make_unique> (sm::vec({1.5,0,0})+izoff); - v.bindmodel (gp); + gp->set_parent (v.get_id()); gp->twodimensional (twodee); gp->setsize (1.6, 1.6); gp->xlabel = "v"; diff --git a/mplot/ScatterVisual.h b/mplot/ScatterVisual.h index 51f9f55a..910a7922 100644 --- a/mplot/ScatterVisual.h +++ b/mplot/ScatterVisual.h @@ -4,17 +4,20 @@ * \author Seb James * \date 2019 */ -#pragma once +module; #include #include #include + +export module mplot.scattervisual; + import sm.vec; -#include -#include -#include +import mplot.tools; +export import mplot.visualdatamodel; +export import mplot.graphstyles; -namespace mplot +export namespace mplot { //! The template argument Flt is the type of the data which this ScatterVisual //! will visualize. diff --git a/mplot/TriaxesVisual.h b/mplot/TriaxesVisual.h index 699d5580..90e93352 100644 --- a/mplot/TriaxesVisual.h +++ b/mplot/TriaxesVisual.h @@ -3,17 +3,26 @@ * box. Use along with ScatterVisual or HexGridVisual for plotting 3D graph * visualisations. */ -#pragma once +module; +#include +#include +#include +#include #include + +export module mplot.triaxesvisual; + import sm.scale; import sm.vec; import sm.quaternion; -#include -#include -#include // Share tickstyle, axestyle -namespace mplot +import mplot.visualmodel; +import mplot.visualfont; +import mplot.graphing; +import mplot.graphstyles; // Share tickstyle, axestyle + +export namespace mplot { template class TriaxesVisual : public VisualModel @@ -254,7 +263,6 @@ namespace mplot // y axis label (have to rotate) lbl = this->makeVisualTextModel (tf); - this->bindmodel (lbl); geom = lbl->getTextGeometry (this->ylabel); // Rotate label if it's long diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index d7d01e4d..8f38e9d6 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -40,13 +40,6 @@ module; #include -// Use Lode Vandevenne's PNG encoder -#define LODEPNG_NO_COMPILE_DECODER 1 -#define LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS 1 -#include - -#include - export module mplot.visualownable; export import mplot.visualmodel; @@ -60,6 +53,7 @@ import mplot.coordarrows; export import mplot.gl.version; import mplot.gl.util; import mplot.tools; +import mplot.loadpng; // Use Lode Vandevenne's PNG encoder export import sm.vec; export import sm.flags; @@ -394,9 +388,9 @@ export namespace mplot } } } - uint32_t error = lodepng::encode (img_filename, rbits.get(), dims[0], dims[1]); + uint32_t error = mplot::png_encode (img_filename, rbits.get(), dims[0], dims[1]); if (error) { - std::cerr << "encoder error " << error << ": " << lodepng_error_text (error) << std::endl; + std::cerr << "encoder error " << error << ": " << mplot::png_error_text (error) << std::endl; dims.set_from (-1); return dims; } diff --git a/mplot/VisualTextModel.h b/mplot/VisualTextModel.h index 0666ac62..885f6a27 100644 --- a/mplot/VisualTextModel.h +++ b/mplot/VisualTextModel.h @@ -27,15 +27,14 @@ module; #include -#include - export module mplot.visualtextmodel; import mplot.visualresources; import mplot.visualcommon; export import mplot.textgeometry; export import mplot.textfeatures; -import mplot.visualface; +export import mplot.unicode; +export import mplot.visualface; import mplot.colour; import mplot.gl.version; import mplot.gl.util; diff --git a/mplot/loadpng.h b/mplot/loadpng.h index 833cf5ff..11070266 100644 --- a/mplot/loadpng.h +++ b/mplot/loadpng.h @@ -1,24 +1,33 @@ -#pragma once - /* * Helper to load PNG images into mplot::vvec> format and similar. - * - * Note: You have to #include this before mplot/Visual.h */ +module; + #define LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS 1 #include +#include #include #include #include #include #include -import sm.vec; +export module mplot.loadpng; + +export import sm.vec; import sm.vvec; -namespace mplot +export namespace mplot { + uint32_t png_encode (const std::string& img_filename, const unsigned char* in, int32_t w, int32_t h) + { + if (w < 0 || h < 0) { return std::numeric_limits::max(); } + return lodepng::encode (img_filename, in, w, h); + } + + std::string png_error_text (const uint32_t error) { return lodepng_error_text (error); } + /* * Wrap lodepng::decode to load a PNG from file, placing the data into the * image_data array. Figure out based on the type of T, how to scale the numbers. @@ -35,8 +44,8 @@ namespace mplot * image_data will be filled in a bottom-left to top-right order. */ template - static sm::vec loadpng (const std::string& filename, sm::vvec& image_data, - const sm::vec flip = {false, true}) + sm::vec loadpng (const std::string& filename, sm::vvec& image_data, + const sm::vec flip = {false, true}) { std::vector png; unsigned int w = 0; @@ -116,9 +125,9 @@ namespace mplot * to errors) */ template - static sm::vec loadpng (const std::string& filename, - sm::vvec>& image_data, - const sm::vec flip = {false, true}) + sm::vec loadpng (const std::string& filename, + sm::vvec>& image_data, + const sm::vec flip = {false, true}) { std::vector png; unsigned int w = 0; @@ -199,8 +208,8 @@ namespace mplot // Load a colour PNG and return a vector of type T with elements ordered as RGBRGBRGB... template - static sm::vec loadpng_rgb (const std::string& filename, sm::vvec& image_data, - const sm::vec flip = {false, true}) + sm::vec loadpng_rgb (const std::string& filename, sm::vvec& image_data, + const sm::vec flip = {false, true}) { std::vector png; unsigned int w = 0; @@ -264,8 +273,8 @@ namespace mplot // Load a colour PNG and return a vector of type T with elements ordered as RGBARGBARGBA... template - static sm::vec loadpng_rgba (const std::string& filename, sm::vvec& image_data, - const sm::vec flip = {false, true}) + sm::vec loadpng_rgba (const std::string& filename, sm::vvec& image_data, + const sm::vec flip = {false, true}) { std::vector png; unsigned int w = 0; @@ -332,8 +341,8 @@ namespace mplot // Load a colour PNG and return a vector of type T with elements ordered as RGBARGBARGBA... template - static sm::vec loadpng_rgba (const std::string& filename, sm::vec& image_data, - const sm::vec flip = {false, true}) + sm::vec loadpng_rgba (const std::string& filename, sm::vec& image_data, + const sm::vec flip = {false, true}) { std::vector png; unsigned int w = 0; diff --git a/mplot/unicode.h b/mplot/unicode.h index 8d88d0c1..fea22aef 100644 --- a/mplot/unicode.h +++ b/mplot/unicode.h @@ -6,12 +6,13 @@ * \author Seb James * \date January 2022 */ - -#pragma once +module; #include -namespace mplot::unicode +export module mplot.unicode; + +export namespace mplot::unicode { /* * These constants are defined to make program code that uses unicode::toUtf8() @@ -19,140 +20,140 @@ namespace mplot::unicode */ // Greek lower case letters - static constexpr char32_t alpha = 0x03b1; - static constexpr char32_t beta = 0x03b2; - static constexpr char32_t gamma = 0x03b3; - static constexpr char32_t delta = 0x03b4; - static constexpr char32_t epsilon = 0x03b5; - static constexpr char32_t zeta = 0x03b6; - static constexpr char32_t eta = 0x03b7; - static constexpr char32_t theta = 0x03b8; - static constexpr char32_t iota = 0x03b9; - static constexpr char32_t kappa = 0x03ba; - static constexpr char32_t lambda = 0x03bb; - static constexpr char32_t mu = 0x03bc; - static constexpr char32_t nu = 0x03bd; - static constexpr char32_t xi = 0x03be; - static constexpr char32_t omicron = 0x03bf; - static constexpr char32_t pi = 0x03c0; - static constexpr char32_t rho = 0x03c1; - static constexpr char32_t finalsigma = 0x03c2; - static constexpr char32_t sigma = 0x03c3; - static constexpr char32_t tau = 0x03c4; - static constexpr char32_t upsilon = 0x03c5; - static constexpr char32_t phi = 0x03c6; - static constexpr char32_t chi = 0x03c7; - static constexpr char32_t psi = 0x03c8; - static constexpr char32_t omega = 0x03c9; + constexpr char32_t alpha = 0x03b1; + constexpr char32_t beta = 0x03b2; + constexpr char32_t gamma = 0x03b3; + constexpr char32_t delta = 0x03b4; + constexpr char32_t epsilon = 0x03b5; + constexpr char32_t zeta = 0x03b6; + constexpr char32_t eta = 0x03b7; + constexpr char32_t theta = 0x03b8; + constexpr char32_t iota = 0x03b9; + constexpr char32_t kappa = 0x03ba; + constexpr char32_t lambda = 0x03bb; + constexpr char32_t mu = 0x03bc; + constexpr char32_t nu = 0x03bd; + constexpr char32_t xi = 0x03be; + constexpr char32_t omicron = 0x03bf; + constexpr char32_t pi = 0x03c0; + constexpr char32_t rho = 0x03c1; + constexpr char32_t finalsigma = 0x03c2; + constexpr char32_t sigma = 0x03c3; + constexpr char32_t tau = 0x03c4; + constexpr char32_t upsilon = 0x03c5; + constexpr char32_t phi = 0x03c6; + constexpr char32_t chi = 0x03c7; + constexpr char32_t psi = 0x03c8; + constexpr char32_t omega = 0x03c9; // Greek upper case letters - static constexpr char32_t Alpha = 0x0391; - static constexpr char32_t Beta = 0x0392; - static constexpr char32_t Gamma = 0x0393; - static constexpr char32_t Delta = 0x0394; - static constexpr char32_t Epsilon = 0x0395; - static constexpr char32_t Zeta = 0x0396; - static constexpr char32_t Eta = 0x0397; - static constexpr char32_t Theta = 0x0398; - static constexpr char32_t Iota = 0x0399; - static constexpr char32_t Kappa = 0x039a; - static constexpr char32_t Lambda = 0x039b; - static constexpr char32_t Mu = 0x039c; - static constexpr char32_t Nu = 0x039d; - static constexpr char32_t Xi = 0x039e; - static constexpr char32_t Omicron = 0x039f; - static constexpr char32_t Pi = 0x03a0; - static constexpr char32_t Rho = 0x03a1; - static constexpr char32_t Sigma = 0x03a3; - static constexpr char32_t Tau = 0x03a4; - static constexpr char32_t Upsilon = 0x03a5; - static constexpr char32_t Phi = 0x03a6; - static constexpr char32_t Chi = 0x03a7; - static constexpr char32_t Psi = 0x03a8; - static constexpr char32_t Omega = 0x03a9; + constexpr char32_t Alpha = 0x0391; + constexpr char32_t Beta = 0x0392; + constexpr char32_t Gamma = 0x0393; + constexpr char32_t Delta = 0x0394; + constexpr char32_t Epsilon = 0x0395; + constexpr char32_t Zeta = 0x0396; + constexpr char32_t Eta = 0x0397; + constexpr char32_t Theta = 0x0398; + constexpr char32_t Iota = 0x0399; + constexpr char32_t Kappa = 0x039a; + constexpr char32_t Lambda = 0x039b; + constexpr char32_t Mu = 0x039c; + constexpr char32_t Nu = 0x039d; + constexpr char32_t Xi = 0x039e; + constexpr char32_t Omicron = 0x039f; + constexpr char32_t Pi = 0x03a0; + constexpr char32_t Rho = 0x03a1; + constexpr char32_t Sigma = 0x03a3; + constexpr char32_t Tau = 0x03a4; + constexpr char32_t Upsilon = 0x03a5; + constexpr char32_t Phi = 0x03a6; + constexpr char32_t Chi = 0x03a7; + constexpr char32_t Psi = 0x03a8; + constexpr char32_t Omega = 0x03a9; // Math symbols - static constexpr char32_t plusminus = 0x00b1; - static constexpr char32_t minusplus = 0x2213; - static constexpr char32_t divides = 0x00f7; - static constexpr char32_t multiplies = 0x00d7; - static constexpr char32_t forall = 0x2200; - static constexpr char32_t exists = 0x2203; - static constexpr char32_t nabla = 0x2207; - static constexpr char32_t piproduct = 0x220f; - static constexpr char32_t sigmasum = 0x2211; - static constexpr char32_t sqrt = 0x221a; - static constexpr char32_t cubert = 0x221b; - static constexpr char32_t infinity = 0x221e; - static constexpr char32_t notequal = 0x2260; - static constexpr char32_t almostequal = 0x2248; - static constexpr char32_t asympequal = 0x2243; - static constexpr char32_t approxequal = 0x2245; - static constexpr char32_t degreesign = 0x00b0; - static constexpr char32_t perpendicular = 0x27c2; - static constexpr char32_t parrallelto = 0x2225; - static constexpr char32_t proportionalto = 0x221d; - static constexpr char32_t integral = 0x222b; - static constexpr char32_t doubleintegral = 0x222c; - static constexpr char32_t tripleintegral = 0x222d; - static constexpr char32_t contourintegral = 0x222e; - static constexpr char32_t surfaceintegral = 0x222f; - static constexpr char32_t volumeintegral = 0x2230; + constexpr char32_t plusminus = 0x00b1; + constexpr char32_t minusplus = 0x2213; + constexpr char32_t divides = 0x00f7; + constexpr char32_t multiplies = 0x00d7; + constexpr char32_t forall = 0x2200; + constexpr char32_t exists = 0x2203; + constexpr char32_t nabla = 0x2207; + constexpr char32_t piproduct = 0x220f; + constexpr char32_t sigmasum = 0x2211; + constexpr char32_t sqrt = 0x221a; + constexpr char32_t cubert = 0x221b; + constexpr char32_t infinity = 0x221e; + constexpr char32_t notequal = 0x2260; + constexpr char32_t almostequal = 0x2248; + constexpr char32_t asympequal = 0x2243; + constexpr char32_t approxequal = 0x2245; + constexpr char32_t degreesign = 0x00b0; + constexpr char32_t perpendicular = 0x27c2; + constexpr char32_t parrallelto = 0x2225; + constexpr char32_t proportionalto = 0x221d; + constexpr char32_t integral = 0x222b; + constexpr char32_t doubleintegral = 0x222c; + constexpr char32_t tripleintegral = 0x222d; + constexpr char32_t contourintegral = 0x222e; + constexpr char32_t surfaceintegral = 0x222f; + constexpr char32_t volumeintegral = 0x2230; // Arrers - static constexpr char32_t leftarrow = 0x2190; - static constexpr char32_t uparrow = 0x2191; - static constexpr char32_t rightarrow = 0x2192; - static constexpr char32_t downarrow = 0x2193; - static constexpr char32_t rightarrow2 = 0x1f812; - static constexpr char32_t longrightarrow = 0x27f6; - static constexpr char32_t longleftarrow = 0x27f5; - static constexpr char32_t longleftrightarrow = 0x27f7; - static constexpr char32_t line_emdash = 0x2014; - static constexpr char32_t line_horzbar = 0x2015; + constexpr char32_t leftarrow = 0x2190; + constexpr char32_t uparrow = 0x2191; + constexpr char32_t rightarrow = 0x2192; + constexpr char32_t downarrow = 0x2193; + constexpr char32_t rightarrow2 = 0x1f812; + constexpr char32_t longrightarrow = 0x27f6; + constexpr char32_t longleftarrow = 0x27f5; + constexpr char32_t longleftrightarrow = 0x27f7; + constexpr char32_t line_emdash = 0x2014; + constexpr char32_t line_horzbar = 0x2015; // Superscripts - static constexpr char32_t ss0 = 0x2070; - static constexpr char32_t ss1 = 0x00b9; - static constexpr char32_t ss2 = 0x00b2; - static constexpr char32_t ss3 = 0x00b3; - static constexpr char32_t ss4 = 0x2074; - static constexpr char32_t ss5 = 0x2075; - static constexpr char32_t ss6 = 0x2076; - static constexpr char32_t ss7 = 0x2077; - static constexpr char32_t ss8 = 0x2078; - static constexpr char32_t ss9 = 0x2079; - static constexpr char32_t ssplus = 0x207a; - static constexpr char32_t ssminus = 0x207b; - static constexpr char32_t ssequals = 0x207c; - static constexpr char32_t ssleftbracket = 0x207d; - static constexpr char32_t ssrightbracket = 0x207e; + constexpr char32_t ss0 = 0x2070; + constexpr char32_t ss1 = 0x00b9; + constexpr char32_t ss2 = 0x00b2; + constexpr char32_t ss3 = 0x00b3; + constexpr char32_t ss4 = 0x2074; + constexpr char32_t ss5 = 0x2075; + constexpr char32_t ss6 = 0x2076; + constexpr char32_t ss7 = 0x2077; + constexpr char32_t ss8 = 0x2078; + constexpr char32_t ss9 = 0x2079; + constexpr char32_t ssplus = 0x207a; + constexpr char32_t ssminus = 0x207b; + constexpr char32_t ssequals = 0x207c; + constexpr char32_t ssleftbracket = 0x207d; + constexpr char32_t ssrightbracket = 0x207e; // Subscripts - static constexpr char32_t subs0 = 0x2080; - static constexpr char32_t subs1 = 0x2081; - static constexpr char32_t subs2 = 0x2082; - static constexpr char32_t subs3 = 0x2083; - static constexpr char32_t subs4 = 0x2084; - static constexpr char32_t subs5 = 0x2085; - static constexpr char32_t subs6 = 0x2086; - static constexpr char32_t subs7 = 0x2087; - static constexpr char32_t subs8 = 0x2088; - static constexpr char32_t subs9 = 0x2089; + constexpr char32_t subs0 = 0x2080; + constexpr char32_t subs1 = 0x2081; + constexpr char32_t subs2 = 0x2082; + constexpr char32_t subs3 = 0x2083; + constexpr char32_t subs4 = 0x2084; + constexpr char32_t subs5 = 0x2085; + constexpr char32_t subs6 = 0x2086; + constexpr char32_t subs7 = 0x2087; + constexpr char32_t subs8 = 0x2088; + constexpr char32_t subs9 = 0x2089; - static constexpr char32_t subsplus = 0x208a; - static constexpr char32_t subsminus = 0x208b; - static constexpr char32_t subsequals = 0x208c; - static constexpr char32_t subsleftbracket = 0x208d; - static constexpr char32_t subsrightbracket = 0x208e; + constexpr char32_t subsplus = 0x208a; + constexpr char32_t subsminus = 0x208b; + constexpr char32_t subsequals = 0x208c; + constexpr char32_t subsleftbracket = 0x208d; + constexpr char32_t subsrightbracket = 0x208e; // Comparison - static constexpr char32_t lessthaneq = 0x2264; - static constexpr char32_t greaterthaneq = 0x2265; - static constexpr char32_t notlessthan = 0x226e; - static constexpr char32_t notgreaterthan = 0x226f; - static constexpr char32_t lessthanapproxeq = 0x2272; - static constexpr char32_t greaterthanapproxeq = 0x2273; + constexpr char32_t lessthaneq = 0x2264; + constexpr char32_t greaterthaneq = 0x2265; + constexpr char32_t notlessthan = 0x226e; + constexpr char32_t notgreaterthan = 0x226f; + constexpr char32_t lessthanapproxeq = 0x2272; + constexpr char32_t greaterthanapproxeq = 0x2273; //! Convert an input 8 bit string encoded in UTF-8 (or ASCII) format into an //! output string of unicode characters. From 5f3751439235c193cc5640a280554bd3c42c8c3f Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 12 Mar 2026 12:35:02 +0000 Subject: [PATCH 057/106] Changes necessary to compile all of antpov --- maths | 2 +- mplot/LengthscaleVisual.h | 13 ++++++++----- mplot/QuiverVisual.h | 17 +++++++++++------ 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/maths b/maths index 0d93dde3..3563e804 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit 0d93dde36be8c9a490a3ac4c6ca24b16b667939f +Subproject commit 3563e80440679fa0ae2ff1ff48beb06e4422477c diff --git a/mplot/LengthscaleVisual.h b/mplot/LengthscaleVisual.h index d38865c9..b51fadfd 100644 --- a/mplot/LengthscaleVisual.h +++ b/mplot/LengthscaleVisual.h @@ -1,19 +1,22 @@ /* * This is a VisualModel to place a length marker in your scene */ - -#pragma once +module; #include +#include +#include #include + +export module mplot.lengthscalevisual; + +import mplot.visualmodel; import sm.vec; import sm.scale; import sm.quaternion; -#include - -namespace mplot +export namespace mplot { //! A length scale marker template diff --git a/mplot/QuiverVisual.h b/mplot/QuiverVisual.h index bc59555e..5b4dce80 100644 --- a/mplot/QuiverVisual.h +++ b/mplot/QuiverVisual.h @@ -1,21 +1,26 @@ -#pragma once +module; +#include #include #include #include #include #include +#include + +export module mplot.quivervisual; import sm.scale; import sm.vec; import sm.vvec; -#include -#include -#include -#include +import mplot.tools; +import mplot.visualdatamodel; +export import mplot.colour; +export import mplot.colourmap; +export import mplot.graphstyles; -namespace mplot +export namespace mplot { //! A class to make quiver plots template From 7b0c72ff9d6f6a649cd01a8919b0577387d20fa9 Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 12 Mar 2026 15:27:50 +0000 Subject: [PATCH 058/106] Get the examples building with modularized mathconst and constexpr_math --- examples/CMakeLists.txt | 646 ++++----------------------- examples/breadcrumbs.cpp | 2 +- examples/ellipsoid.cpp | 4 +- examples/showcase.cpp | 2 +- maths | 2 +- mplot/ColourMap.h | 3 +- mplot/CurvyTellyVisual.h | 15 +- mplot/CyclicColourVisual.h | 13 +- mplot/GraphVisual.h | 3 +- mplot/GratingVisual.h | 13 +- mplot/HSVWheelVisual.h | 13 +- mplot/IcosaVisual.h | 11 +- mplot/LengthscaleVisual.h | 3 +- mplot/PolarVisual.h | 20 +- mplot/RectangleVisual.h | 11 +- mplot/RodVisual.h | 2 +- mplot/SphericalProjectionVisual.h | 19 +- mplot/TriaxesVisual.h | 2 +- mplot/VisualModel.h | 3 +- mplot/VisualOwnable.h | 3 +- mplot/VisualTextModel.h | 3 +- mplot/compoundray/EyeVisual.h | 2 +- mplot/graphing.h | 3 +- mplot/healpix/healpix_astrometry.hpp | 3 +- mplot/healpix/healpix_bare.hpp | 3 +- mplot/jcvoronoi/jc_voronoi.h | 3 +- 26 files changed, 183 insertions(+), 624 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index dbd8e807..b1953802 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,37 +1,35 @@ # All #includes in test programs have to be #include include_directories(BEFORE ${PROJECT_SOURCE_DIR}) -# Each C++ module file has to be listed here (as they don't have a .cppm or .ixx file suffix) -set_source_files_properties ( +set(SM_CORE_MODULES + ${PROJECT_SOURCE_DIR}/maths/sm/mathconst + ${PROJECT_SOURCE_DIR}/maths/sm/constexpr_math ${PROJECT_SOURCE_DIR}/maths/sm/range ${PROJECT_SOURCE_DIR}/maths/sm/random ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/vvec - ${PROJECT_SOURCE_DIR}/maths/sm/scale - ${PROJECT_SOURCE_DIR}/maths/sm/hdfdata ${PROJECT_SOURCE_DIR}/maths/sm/quaternion ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/hex - ${PROJECT_SOURCE_DIR}/maths/sm/hexgrid - ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord - ${PROJECT_SOURCE_DIR}/maths/sm/binomial - ${PROJECT_SOURCE_DIR}/maths/sm/bezcurve - ${PROJECT_SOURCE_DIR}/maths/sm/bezcurvepath - ${PROJECT_SOURCE_DIR}/maths/sm/winder - ${PROJECT_SOURCE_DIR}/maths/sm/bootstrap - ${PROJECT_SOURCE_DIR}/maths/sm/grid + ${PROJECT_SOURCE_DIR}/maths/sm/util + ${PROJECT_SOURCE_DIR}/maths/sm/base64 + ${PROJECT_SOURCE_DIR}/maths/sm/crc32 + ${PROJECT_SOURCE_DIR}/maths/sm/flags ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex - ${PROJECT_SOURCE_DIR}/maths/sm/histo - ${PROJECT_SOURCE_DIR}/maths/sm/boxfilter ${PROJECT_SOURCE_DIR}/maths/sm/geometry ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra - ${PROJECT_SOURCE_DIR}/maths/sm/flags + ${PROJECT_SOURCE_DIR}/maths/sm/vvec + ${PROJECT_SOURCE_DIR}/maths/sm/scale ${PROJECT_SOURCE_DIR}/maths/sm/centroid - ${PROJECT_SOURCE_DIR}/maths/sm/util - ${PROJECT_SOURCE_DIR}/maths/sm/base64 - ${PROJECT_SOURCE_DIR}/maths/sm/crc32 - +) +# Base modules for mathplot +set(MPLOT_CORE_MODULES + ${PROJECT_SOURCE_DIR}/mplot/tools.h + ${PROJECT_SOURCE_DIR}/mplot/unicode.h + ${PROJECT_SOURCE_DIR}/mplot/loadpng.h + ${PROJECT_SOURCE_DIR}/mplot/gl/version.h + ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h + ${PROJECT_SOURCE_DIR}/mplot/colour.h + ${PROJECT_SOURCE_DIR}/mplot/win_t.h + ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h ${PROJECT_SOURCE_DIR}/mplot/Visual.h ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h @@ -43,632 +41,166 @@ set_source_files_properties ( ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.h ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h - ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h - ${PROJECT_SOURCE_DIR}/mplot/win_t.h - ${PROJECT_SOURCE_DIR}/mplot/colour.h - ${PROJECT_SOURCE_DIR}/mplot/tools.h - ${PROJECT_SOURCE_DIR}/mplot/unicode.h - ${PROJECT_SOURCE_DIR}/mplot/loadpng.h - ${PROJECT_SOURCE_DIR}/mplot/gl/version.h - ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h - ${PROJECT_SOURCE_DIR}/mplot/graphing.h ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h ${PROJECT_SOURCE_DIR}/mplot/DatasetStyle.h - ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h + ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.h +) - ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h +# Maths used in individual VisualModels, but not the mathplot core +set(SM_VISUALMODEL_MODULES + ${PROJECT_SOURCE_DIR}/maths/sm/winder + ${PROJECT_SOURCE_DIR}/maths/sm/histo + ${PROJECT_SOURCE_DIR}/maths/sm/grid + ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex + ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord + ${PROJECT_SOURCE_DIR}/maths/sm/binomial + ${PROJECT_SOURCE_DIR}/maths/sm/bezcurve + ${PROJECT_SOURCE_DIR}/maths/sm/bezcurvepath + ${PROJECT_SOURCE_DIR}/maths/sm/hex + ${PROJECT_SOURCE_DIR}/maths/sm/hexgrid +) - ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h +# The modules required for hexgrids +set(SM_HEXGRID_MODULES + ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex + ${PROJECT_SOURCE_DIR}/maths/sm/binomial + ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord + ${PROJECT_SOURCE_DIR}/maths/sm/bezcurve + ${PROJECT_SOURCE_DIR}/maths/sm/bezcurvepath + ${PROJECT_SOURCE_DIR}/maths/sm/hex + ${PROJECT_SOURCE_DIR}/maths/sm/hexgrid +) +set(MPLOT_VISUALMODEL_MODULES + ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h + ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h + ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.h - ${PROJECT_SOURCE_DIR}/mplot/SphereVisual.h - ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.h - ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.h - ${PROJECT_SOURCE_DIR}/mplot/compoundray/EyeVisual.h - ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.h - ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.h - ${PROJECT_SOURCE_DIR}/mplot/TriaxesVisual.h - ${PROJECT_SOURCE_DIR}/mplot/ScatterVisual.h +) +# Each C++ module file has to be listed here (as they don't have a .cppm or .ixx file suffix) +set_source_files_properties ( + ${SM_CORE_MODULES} + ${MPLOT_CORE_MODULES} + ${SM_VISUALMODEL_MODULES} + ${MPLOT_VISUALMODEL_MODULES} PROPERTIES LANGUAGE CXX ) add_executable(helloworld helloworld.cpp) target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES - ${PROJECT_SOURCE_DIR}/mplot/tools.h - ${PROJECT_SOURCE_DIR}/mplot/unicode.h - ${PROJECT_SOURCE_DIR}/mplot/loadpng.h - ${PROJECT_SOURCE_DIR}/mplot/gl/version.h - ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h - ${PROJECT_SOURCE_DIR}/mplot/colour.h - ${PROJECT_SOURCE_DIR}/mplot/win_t.h - ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h - ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h - ${PROJECT_SOURCE_DIR}/mplot/Visual.h - ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h - ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h - ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h - ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h - ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h - ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h - ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h - ${PROJECT_SOURCE_DIR}/maths/sm/util - ${PROJECT_SOURCE_DIR}/maths/sm/base64 - ${PROJECT_SOURCE_DIR}/maths/sm/crc32 - ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/range - ${PROJECT_SOURCE_DIR}/maths/sm/random - ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion - ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/geometry - ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra - ${PROJECT_SOURCE_DIR}/maths/sm/vvec) + FILES ${MPLOT_CORE_MODULES} ${SM_CORE_MODULES}) target_link_libraries(helloworld OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) add_executable(rod rod.cpp) target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES - ${PROJECT_SOURCE_DIR}/mplot/tools.h - ${PROJECT_SOURCE_DIR}/mplot/unicode.h - ${PROJECT_SOURCE_DIR}/mplot/loadpng.h - ${PROJECT_SOURCE_DIR}/mplot/gl/version.h - ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h - ${PROJECT_SOURCE_DIR}/mplot/colour.h - ${PROJECT_SOURCE_DIR}/mplot/win_t.h - ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h - ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h - ${PROJECT_SOURCE_DIR}/mplot/Visual.h - ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h - ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h - ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h - ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h - ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h - ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h - ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h - ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h - ${PROJECT_SOURCE_DIR}/maths/sm/util - ${PROJECT_SOURCE_DIR}/maths/sm/base64 - ${PROJECT_SOURCE_DIR}/maths/sm/crc32 - ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/range - ${PROJECT_SOURCE_DIR}/maths/sm/random - ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion - ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/geometry - ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra - ${PROJECT_SOURCE_DIR}/maths/sm/vvec) + FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h +) target_link_libraries(rod OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) add_executable(rod_with_normals rod_with_normals.cpp) target_sources(rod_with_normals PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES - ${PROJECT_SOURCE_DIR}/mplot/tools.h - ${PROJECT_SOURCE_DIR}/mplot/unicode.h - ${PROJECT_SOURCE_DIR}/mplot/loadpng.h - ${PROJECT_SOURCE_DIR}/mplot/gl/version.h - ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h - ${PROJECT_SOURCE_DIR}/mplot/colour.h - ${PROJECT_SOURCE_DIR}/mplot/win_t.h - ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h - ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h - ${PROJECT_SOURCE_DIR}/mplot/Visual.h - ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h - ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h - ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h - ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h - ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h - ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h - ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h - ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h - ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h - ${PROJECT_SOURCE_DIR}/maths/sm/util - ${PROJECT_SOURCE_DIR}/maths/sm/base64 - ${PROJECT_SOURCE_DIR}/maths/sm/crc32 - ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/range - ${PROJECT_SOURCE_DIR}/maths/sm/random - ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion - ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/geometry - ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra - ${PROJECT_SOURCE_DIR}/maths/sm/vvec) + FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.h + ) target_link_libraries(rod_with_normals OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) add_executable(ellipsoid ellipsoid.cpp) target_sources(ellipsoid PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES - ${PROJECT_SOURCE_DIR}/mplot/tools.h - ${PROJECT_SOURCE_DIR}/mplot/unicode.h - ${PROJECT_SOURCE_DIR}/mplot/loadpng.h - ${PROJECT_SOURCE_DIR}/mplot/gl/version.h - ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h - ${PROJECT_SOURCE_DIR}/mplot/colour.h - ${PROJECT_SOURCE_DIR}/mplot/win_t.h - ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h - ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h - ${PROJECT_SOURCE_DIR}/mplot/Visual.h - ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h - ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h - ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h - ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h - ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h - ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h - ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h - ${PROJECT_SOURCE_DIR}/maths/sm/util - ${PROJECT_SOURCE_DIR}/maths/sm/base64 - ${PROJECT_SOURCE_DIR}/maths/sm/crc32 - ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/range - ${PROJECT_SOURCE_DIR}/maths/sm/random - ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion - ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/geometry - ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra - ${PROJECT_SOURCE_DIR}/maths/sm/vvec) +) target_link_libraries(ellipsoid OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) if(NOT APPLE) add_executable(geodesic geodesic.cpp) target_sources(geodesic PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES - ${PROJECT_SOURCE_DIR}/mplot/tools.h - ${PROJECT_SOURCE_DIR}/mplot/unicode.h - ${PROJECT_SOURCE_DIR}/mplot/loadpng.h - ${PROJECT_SOURCE_DIR}/mplot/gl/version.h - ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h - ${PROJECT_SOURCE_DIR}/mplot/colour.h - ${PROJECT_SOURCE_DIR}/mplot/win_t.h - ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h - ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h - ${PROJECT_SOURCE_DIR}/mplot/Visual.h - ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h - ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h - ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h - ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h - ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h - ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h - ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.h ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h - ${PROJECT_SOURCE_DIR}/maths/sm/scale - ${PROJECT_SOURCE_DIR}/maths/sm/util - ${PROJECT_SOURCE_DIR}/maths/sm/base64 - ${PROJECT_SOURCE_DIR}/maths/sm/crc32 - ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/range - ${PROJECT_SOURCE_DIR}/maths/sm/random - ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion - ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/geometry - ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra - ${PROJECT_SOURCE_DIR}/maths/sm/vvec) +) target_link_libraries(geodesic OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) endif() add_executable(vectorvis vectorvis.cpp) target_sources(vectorvis PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES - ${PROJECT_SOURCE_DIR}/mplot/tools.h - ${PROJECT_SOURCE_DIR}/mplot/unicode.h - ${PROJECT_SOURCE_DIR}/mplot/loadpng.h - ${PROJECT_SOURCE_DIR}/mplot/gl/version.h - ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h - ${PROJECT_SOURCE_DIR}/mplot/colour.h - ${PROJECT_SOURCE_DIR}/mplot/win_t.h - ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h - ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h - ${PROJECT_SOURCE_DIR}/mplot/Visual.h - ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h - ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h - ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h - ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h - ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h - ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h - ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h + FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h - ${PROJECT_SOURCE_DIR}/maths/sm/util - ${PROJECT_SOURCE_DIR}/maths/sm/base64 - ${PROJECT_SOURCE_DIR}/maths/sm/crc32 - ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/range - ${PROJECT_SOURCE_DIR}/maths/sm/random - ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion - ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/geometry - ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra - ${PROJECT_SOURCE_DIR}/maths/sm/vvec) +) target_link_libraries(vectorvis OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) add_executable(cray_eye cray_eye.cpp) target_sources(cray_eye PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES - ${PROJECT_SOURCE_DIR}/mplot/tools.h - ${PROJECT_SOURCE_DIR}/mplot/unicode.h - ${PROJECT_SOURCE_DIR}/mplot/loadpng.h - ${PROJECT_SOURCE_DIR}/mplot/gl/version.h - ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h - ${PROJECT_SOURCE_DIR}/mplot/colour.h - ${PROJECT_SOURCE_DIR}/mplot/win_t.h - ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h - ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h - ${PROJECT_SOURCE_DIR}/mplot/Visual.h - ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h - ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h - ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h - ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h - ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h - ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h - ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h - + FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/SphereVisual.h ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.h - ${PROJECT_SOURCE_DIR}/mplot/compoundray/EyeVisual.h - - ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h - ${PROJECT_SOURCE_DIR}/maths/sm/util - ${PROJECT_SOURCE_DIR}/maths/sm/base64 - ${PROJECT_SOURCE_DIR}/maths/sm/crc32 ${PROJECT_SOURCE_DIR}/maths/sm/winder - ${PROJECT_SOURCE_DIR}/maths/sm/centroid - ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/range - ${PROJECT_SOURCE_DIR}/maths/sm/random - ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion - ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/geometry - ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra - ${PROJECT_SOURCE_DIR}/maths/sm/vvec) + ${PROJECT_SOURCE_DIR}/mplot/compoundray/EyeVisual.h +) target_link_libraries(cray_eye OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) add_executable(graph1 graph1.cpp) target_sources(graph1 PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES - ${PROJECT_SOURCE_DIR}/mplot/tools.h - ${PROJECT_SOURCE_DIR}/mplot/unicode.h - ${PROJECT_SOURCE_DIR}/mplot/loadpng.h - ${PROJECT_SOURCE_DIR}/mplot/gl/version.h - ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h - ${PROJECT_SOURCE_DIR}/mplot/colour.h - ${PROJECT_SOURCE_DIR}/mplot/win_t.h - ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h - ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h - ${PROJECT_SOURCE_DIR}/mplot/Visual.h - ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h - ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h - ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h - ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h - ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h - ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h - ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h - ${PROJECT_SOURCE_DIR}/mplot/graphing.h - ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h - ${PROJECT_SOURCE_DIR}/mplot/DatasetStyle.h - ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h - ${PROJECT_SOURCE_DIR}/maths/sm/util - ${PROJECT_SOURCE_DIR}/maths/sm/base64 - ${PROJECT_SOURCE_DIR}/maths/sm/crc32 - ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/range - ${PROJECT_SOURCE_DIR}/maths/sm/random - ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/scale + FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/maths/sm/histo ${PROJECT_SOURCE_DIR}/maths/sm/grid - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion - ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/geometry - ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra - ${PROJECT_SOURCE_DIR}/maths/sm/vvec) + ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h +) target_link_libraries(graph1 OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) -# mplot::Grid is runtime-configured +# sm::grid visualization example add_executable(grid_simple grid_simple.cpp) target_sources(grid_simple PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES - ${PROJECT_SOURCE_DIR}/mplot/tools.h - ${PROJECT_SOURCE_DIR}/mplot/unicode.h - ${PROJECT_SOURCE_DIR}/mplot/loadpng.h - ${PROJECT_SOURCE_DIR}/mplot/gl/version.h - ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h - ${PROJECT_SOURCE_DIR}/mplot/colour.h - ${PROJECT_SOURCE_DIR}/mplot/win_t.h - ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h - ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h - ${PROJECT_SOURCE_DIR}/mplot/Visual.h - ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h - ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h - ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h - ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h - ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h - ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.h - ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h - ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h - ${PROJECT_SOURCE_DIR}/maths/sm/util - ${PROJECT_SOURCE_DIR}/maths/sm/base64 - ${PROJECT_SOURCE_DIR}/maths/sm/crc32 - ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/range - ${PROJECT_SOURCE_DIR}/maths/sm/random - ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion - ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/geometry - ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra - ${PROJECT_SOURCE_DIR}/maths/sm/vvec - ${PROJECT_SOURCE_DIR}/maths/sm/scale - ${PROJECT_SOURCE_DIR}/maths/sm/centroid + FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/maths/sm/grid + ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h ) target_link_libraries(grid_simple OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) -# This sphere example uses constexpr code if(NOT APPLE) # Instancing also not available on Apple (limited to OpenGL 4.1) - #add_executable(scatter_instanced scatter_instanced.cpp) - #target_link_libraries(scatter_instanced OpenGL::GL glfw Freetype::Freetype) add_executable(breadcrumbs breadcrumbs.cpp) target_sources(breadcrumbs PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES - ${PROJECT_SOURCE_DIR}/mplot/tools.h - ${PROJECT_SOURCE_DIR}/mplot/unicode.h - ${PROJECT_SOURCE_DIR}/mplot/loadpng.h - ${PROJECT_SOURCE_DIR}/mplot/gl/version.h - ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h - ${PROJECT_SOURCE_DIR}/mplot/colour.h - ${PROJECT_SOURCE_DIR}/mplot/win_t.h - ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h - ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h - ${PROJECT_SOURCE_DIR}/mplot/Visual.h - ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h - ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h - ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h - ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h - ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h - ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h - ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h - ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h - ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.h + FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h - ${PROJECT_SOURCE_DIR}/maths/sm/util - ${PROJECT_SOURCE_DIR}/maths/sm/base64 - ${PROJECT_SOURCE_DIR}/maths/sm/crc32 - ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/range - ${PROJECT_SOURCE_DIR}/maths/sm/random - ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion - ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/geometry - ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra - ${PROJECT_SOURCE_DIR}/maths/sm/vvec - ${PROJECT_SOURCE_DIR}/maths/sm/scale - ${PROJECT_SOURCE_DIR}/maths/sm/centroid - ${PROJECT_SOURCE_DIR}/maths/sm/grid + ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.h ) target_link_libraries(breadcrumbs OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) endif() add_executable(showcase showcase.cpp) target_sources(showcase PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES - ${PROJECT_SOURCE_DIR}/mplot/tools.h - ${PROJECT_SOURCE_DIR}/mplot/unicode.h - ${PROJECT_SOURCE_DIR}/mplot/loadpng.h - ${PROJECT_SOURCE_DIR}/mplot/gl/version.h - ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h - ${PROJECT_SOURCE_DIR}/mplot/colour.h - ${PROJECT_SOURCE_DIR}/mplot/win_t.h - ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h - ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h - ${PROJECT_SOURCE_DIR}/mplot/Visual.h - ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h - ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h - ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h - ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h - ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h - ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.h - ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h - ${PROJECT_SOURCE_DIR}/mplot/graphing.h - ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h - ${PROJECT_SOURCE_DIR}/mplot/DatasetStyle.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h - - ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.h - ${PROJECT_SOURCE_DIR}/mplot/TriaxesVisual.h - ${PROJECT_SOURCE_DIR}/mplot/ScatterVisual.h - ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h - ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h - - ${PROJECT_SOURCE_DIR}/maths/sm/util - ${PROJECT_SOURCE_DIR}/maths/sm/base64 - ${PROJECT_SOURCE_DIR}/maths/sm/crc32 - ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/range - ${PROJECT_SOURCE_DIR}/maths/sm/random - ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion - ${PROJECT_SOURCE_DIR}/maths/sm/histo - ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/geometry - ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra - ${PROJECT_SOURCE_DIR}/maths/sm/vvec - ${PROJECT_SOURCE_DIR}/maths/sm/scale - ${PROJECT_SOURCE_DIR}/maths/sm/centroid - ${PROJECT_SOURCE_DIR}/maths/sm/grid - ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord - ${PROJECT_SOURCE_DIR}/maths/sm/binomial - ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex - ${PROJECT_SOURCE_DIR}/maths/sm/bezcurve - ${PROJECT_SOURCE_DIR}/maths/sm/bezcurvepath - ${PROJECT_SOURCE_DIR}/maths/sm/hex - ${PROJECT_SOURCE_DIR}/maths/sm/hexgrid - ) + FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} + ${SM_HEXGRID_MODULES} + ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.h + ${PROJECT_SOURCE_DIR}/mplot/TriaxesVisual.h + ${PROJECT_SOURCE_DIR}/mplot/ScatterVisual.h + ${PROJECT_SOURCE_DIR}/maths/sm/grid + ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h + ${PROJECT_SOURCE_DIR}/maths/sm/histo + ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h +) target_link_libraries(showcase OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) add_executable(hexgrid hexgrid.cpp) target_sources(hexgrid PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES - ${PROJECT_SOURCE_DIR}/mplot/tools.h - ${PROJECT_SOURCE_DIR}/mplot/unicode.h - ${PROJECT_SOURCE_DIR}/mplot/loadpng.h - ${PROJECT_SOURCE_DIR}/mplot/gl/version.h - ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h - ${PROJECT_SOURCE_DIR}/mplot/colour.h - ${PROJECT_SOURCE_DIR}/mplot/win_t.h - ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h - ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h - ${PROJECT_SOURCE_DIR}/mplot/Visual.h - ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h - ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h - ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h - ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h - ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h - ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h - ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h - ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h - ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.h + FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${SM_HEXGRID_MODULES} ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.h - ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h - ${PROJECT_SOURCE_DIR}/maths/sm/util - ${PROJECT_SOURCE_DIR}/maths/sm/base64 - ${PROJECT_SOURCE_DIR}/maths/sm/crc32 - ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/range - ${PROJECT_SOURCE_DIR}/maths/sm/random - ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion - ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/geometry - ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra - ${PROJECT_SOURCE_DIR}/maths/sm/vvec - ${PROJECT_SOURCE_DIR}/maths/sm/scale - ${PROJECT_SOURCE_DIR}/maths/sm/centroid - ${PROJECT_SOURCE_DIR}/maths/sm/grid - ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord - ${PROJECT_SOURCE_DIR}/maths/sm/binomial - ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex - ${PROJECT_SOURCE_DIR}/maths/sm/bezcurve - ${PROJECT_SOURCE_DIR}/maths/sm/bezcurvepath - ${PROJECT_SOURCE_DIR}/maths/sm/hex - ${PROJECT_SOURCE_DIR}/maths/sm/hexgrid ) target_link_libraries(hexgrid OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) diff --git a/examples/breadcrumbs.cpp b/examples/breadcrumbs.cpp index 61a62e65..b81dafe3 100644 --- a/examples/breadcrumbs.cpp +++ b/examples/breadcrumbs.cpp @@ -7,7 +7,7 @@ #include #include -#include +import sm.mathconst; import sm.scale; import sm.vec; import sm.vvec; diff --git a/examples/ellipsoid.cpp b/examples/ellipsoid.cpp index f8ea6257..865e21f0 100644 --- a/examples/ellipsoid.cpp +++ b/examples/ellipsoid.cpp @@ -7,12 +7,10 @@ #include #include -#include +import sm.mathconst; import sm.mat; import mplot.visual; -//import mplot.visualmodel; -//import mplot.colour; import mplot.normalsvisual; // Quick visual that simply draws ellipsoid diff --git a/examples/showcase.cpp b/examples/showcase.cpp index e43b04d5..e1b4b7c3 100644 --- a/examples/showcase.cpp +++ b/examples/showcase.cpp @@ -3,8 +3,8 @@ #include #include #include -#include +import sm.mathconst; import sm.vvec; import sm.grid; import sm.hexgrid; diff --git a/maths b/maths index 3563e804..36ca9230 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit 3563e80440679fa0ae2ff1ff48beb06e4422477c +Subproject commit 36ca92307b5e8040ec82ac7d8ae5a93842dcd42e diff --git a/mplot/ColourMap.h b/mplot/ColourMap.h index 43e24e0e..e3291009 100644 --- a/mplot/ColourMap.h +++ b/mplot/ColourMap.h @@ -6,8 +6,6 @@ module; #include #include -#include - export module mplot.colourmap; export import :colourmaps_cet; // Colour map tables from CET @@ -15,6 +13,7 @@ export import :colourmaps_crameri; // Colour map tables from Fabio Crameri export import :colourmap_lists; // Colour map tables from matplotlib import mplot.tools; +export import sm.mathconst; import sm.vec; import sm.flags; import sm.crc32; diff --git a/mplot/CurvyTellyVisual.h b/mplot/CurvyTellyVisual.h index b3eeb2f1..5f2ff9b5 100644 --- a/mplot/CurvyTellyVisual.h +++ b/mplot/CurvyTellyVisual.h @@ -1,12 +1,19 @@ -#pragma once +module; +#include +#include #include -#include +#include +#include + +export module mplot.curvytellyvisual; + +import sm.mathconst; import sm.vec; import sm.grid; -#include +import mplot.gridvisual; -namespace mplot +export namespace mplot { /*! * Draw a curved CartGrid like a curved TV. You make a cylinder if you make the rotation diff --git a/mplot/CyclicColourVisual.h b/mplot/CyclicColourVisual.h index 102c12b6..02d5f56a 100644 --- a/mplot/CyclicColourVisual.h +++ b/mplot/CyclicColourVisual.h @@ -1,18 +1,19 @@ /* * A visual to label Cyclic colour maps */ - -#pragma once +module; #include -#include +export module mplot.cycliccolourvisual; + +import sm.mathconst; import sm.vec; -#include -#include +import mplot.unicode; +import mplot.visualmodel; -namespace mplot +export namespace mplot { template class CyclicColourVisual : public VisualModel diff --git a/mplot/GraphVisual.h b/mplot/GraphVisual.h index 6a0f84f1..6fb1ace5 100644 --- a/mplot/GraphVisual.h +++ b/mplot/GraphVisual.h @@ -18,7 +18,6 @@ module; #include #include -#include export module mplot.graphvisual; @@ -26,6 +25,7 @@ import mplot.graphing; export import mplot.graphstyles; export import mplot.datasetstyle; +export import sm.mathconst; import sm.scale; import sm.range; export import sm.vec; @@ -34,7 +34,6 @@ import sm.quaternion; import sm.histo; import sm.grid; - import mplot.tools; import mplot.colour; import mplot.gl.version; diff --git a/mplot/GratingVisual.h b/mplot/GratingVisual.h index 93fc4316..b2bf4d6d 100644 --- a/mplot/GratingVisual.h +++ b/mplot/GratingVisual.h @@ -5,21 +5,22 @@ * Author: Seb James * Date: July 2024 */ - -#pragma once +module; #include #include #include -#include +export module mplot.gratingvisual; + +import sm.mathconst; import sm.vec; import sm.geometry; -#include -#include +export import mplot.colour; +import mplot.visualmodel; -namespace mplot +export namespace mplot { enum class border_id { diff --git a/mplot/HSVWheelVisual.h b/mplot/HSVWheelVisual.h index 813d47ce..e0d3a0b6 100644 --- a/mplot/HSVWheelVisual.h +++ b/mplot/HSVWheelVisual.h @@ -1,16 +1,19 @@ /* * A visual to label HSV graphs */ +module; -#pragma once +#include -#include +export module mplot.hsvwheelvisual; + +import sm.mathconst; import sm.vec; -#include -#include +import mplot.visualmodel; +import mplot.graphvisual; -namespace mplot +export namespace mplot { template class HSVWheelVisual : public VisualModel diff --git a/mplot/IcosaVisual.h b/mplot/IcosaVisual.h index 036e8aa1..951cbfb1 100644 --- a/mplot/IcosaVisual.h +++ b/mplot/IcosaVisual.h @@ -1,11 +1,14 @@ -#pragma once +module; #include -#include + +export module mplot.icosavisual; + +import sm.mathconst; import sm.vec; -#include +import mplot.visualmodel; -namespace mplot +export namespace mplot { //! This class creates the vertices for an icosahedron in a 3D scene. template diff --git a/mplot/LengthscaleVisual.h b/mplot/LengthscaleVisual.h index b51fadfd..2debf0d4 100644 --- a/mplot/LengthscaleVisual.h +++ b/mplot/LengthscaleVisual.h @@ -7,11 +7,10 @@ module; #include #include -#include - export module mplot.lengthscalevisual; import mplot.visualmodel; +import sm.mathconst; import sm.vec; import sm.scale; import sm.quaternion; diff --git a/mplot/PolarVisual.h b/mplot/PolarVisual.h index 0c0b4c18..4b1c8a58 100644 --- a/mplot/PolarVisual.h +++ b/mplot/PolarVisual.h @@ -1,17 +1,25 @@ /* * A visual for polar plots (rho, theta) */ +module; -#pragma once +#include +#include +#include +#include +#include +#include -#include +export module mplot.polarvisual; + +import sm.mathconst; import sm.vec; -#include -#include -#include +import mplot.unicode; +import mplot.visualdatamodel; +import mplot.graphvisual; -namespace mplot +export namespace mplot { template struct PolarVisual : public VisualDataModel diff --git a/mplot/RectangleVisual.h b/mplot/RectangleVisual.h index ba20f87b..030ee1a8 100644 --- a/mplot/RectangleVisual.h +++ b/mplot/RectangleVisual.h @@ -1,12 +1,15 @@ -#pragma once +module; #include + +export module mplot.rectanglevisual; + +import sm.mathconst; import sm.vec; -#include import sm.mat; -#include +import mplot.visualmodel; -namespace mplot +export namespace mplot { //! This class creates the vertices for a simple flat rectangle in a 3D scene. template diff --git a/mplot/RodVisual.h b/mplot/RodVisual.h index 435329b2..15ab7f27 100644 --- a/mplot/RodVisual.h +++ b/mplot/RodVisual.h @@ -2,10 +2,10 @@ module; #include #include -#include export module mplot.rodvisual; +import sm.mathconst; import sm.vec; import mplot.gl.version; export import mplot.visualmodel; diff --git a/mplot/SphericalProjectionVisual.h b/mplot/SphericalProjectionVisual.h index f710ce23..978227ab 100644 --- a/mplot/SphericalProjectionVisual.h +++ b/mplot/SphericalProjectionVisual.h @@ -1,16 +1,23 @@ -#pragma once +module; +#include +#include #include #include -#include +#include +#include + +export module mplot.sphericalprojectionvisual; + +import sm.mathconst; import sm.vec; import sm.range; import sm.geometry; -#include -#include -#include -namespace mplot +import mplot.gl.version; +import mplot.visualmodel; + +export namespace mplot { //! This class creates a flat projection of spherical data provided as vvecs of //! latitude-longitude pairs and scalar or vector values. Use VisualDataModel? diff --git a/mplot/TriaxesVisual.h b/mplot/TriaxesVisual.h index 90e93352..5b9e6793 100644 --- a/mplot/TriaxesVisual.h +++ b/mplot/TriaxesVisual.h @@ -9,10 +9,10 @@ module; #include #include #include -#include export module mplot.triaxesvisual; +export import sm.mathconst; import sm.scale; import sm.vec; import sm.quaternion; diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index 501ebb21..762743ac 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -34,10 +34,9 @@ module; #include #include -#include - export module mplot.visualmodel; +import sm.mathconst; import sm.geometry_polyhedra; import sm.quaternion; import sm.mat; diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index 8f38e9d6..2e937f0a 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -29,8 +29,6 @@ module; #include #include -#include - #include #include @@ -55,6 +53,7 @@ import mplot.gl.util; import mplot.tools; import mplot.loadpng; // Use Lode Vandevenne's PNG encoder +import sm.mathconst; export import sm.vec; export import sm.flags; import sm.quaternion; diff --git a/mplot/VisualTextModel.h b/mplot/VisualTextModel.h index 885f6a27..b0c691f5 100644 --- a/mplot/VisualTextModel.h +++ b/mplot/VisualTextModel.h @@ -25,8 +25,6 @@ module; #include #include -#include - export module mplot.visualtextmodel; import mplot.visualresources; @@ -39,6 +37,7 @@ import mplot.colour; import mplot.gl.version; import mplot.gl.util; +import sm.mathconst; import sm.quaternion; import sm.mat; import sm.vec; diff --git a/mplot/compoundray/EyeVisual.h b/mplot/compoundray/EyeVisual.h index b2285162..2202f463 100644 --- a/mplot/compoundray/EyeVisual.h +++ b/mplot/compoundray/EyeVisual.h @@ -5,11 +5,11 @@ module; #include #include -#include #include export module mplot.compoundray.eyevisual; +export import sm.mathconst; export import sm.vec; import sm.mat; import sm.range; diff --git a/mplot/graphing.h b/mplot/graphing.h index ba5d2ba0..b27a871f 100644 --- a/mplot/graphing.h +++ b/mplot/graphing.h @@ -20,10 +20,9 @@ module; # include #endif -#include - export module mplot.graphing; +import sm.constexpr_math; import sm.range; import sm.algo; import sm.vvec; diff --git a/mplot/healpix/healpix_astrometry.hpp b/mplot/healpix/healpix_astrometry.hpp index afe2fb57..b537b47d 100644 --- a/mplot/healpix/healpix_astrometry.hpp +++ b/mplot/healpix/healpix_astrometry.hpp @@ -6,7 +6,8 @@ */ #pragma once -#include +import sm.mathconst; + #include #include #include diff --git a/mplot/healpix/healpix_bare.hpp b/mplot/healpix/healpix_bare.hpp index 8043dff2..1fec5259 100644 --- a/mplot/healpix/healpix_bare.hpp +++ b/mplot/healpix/healpix_bare.hpp @@ -28,7 +28,8 @@ #include #include #include -#include + +import sm.mathconst; // The healpix namespace contains code from the HEALPix C library, slightly modified. namespace hp diff --git a/mplot/jcvoronoi/jc_voronoi.h b/mplot/jcvoronoi/jc_voronoi.h index b6ad077c..6a51774b 100644 --- a/mplot/jcvoronoi/jc_voronoi.h +++ b/mplot/jcvoronoi/jc_voronoi.h @@ -22,7 +22,8 @@ #include // std::memset #include #include -#include + +import sm.mathconst; import sm.vec; import sm.geometry; import sm.winder; From 945ec328a785c746060c9d4c01ef1158f046ebfe Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 12 Mar 2026 15:44:15 +0000 Subject: [PATCH 059/106] Armadillo is gone! --- CMakeLists.txt | 5 - examples/CMakeLists.txt | 611 ++++++++++++++--------------- examples/pi/CMakeLists.txt | 10 +- examples/qt/fps/CMakeLists.txt | 8 +- examples/qt/hexgrid/CMakeLists.txt | 8 +- tests/CMakeLists.txt | 74 ++-- 6 files changed, 343 insertions(+), 373 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a9cd024..6ad2c48a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,16 +126,11 @@ find_package(HDF5) if(HDF5_FOUND) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${HDF5_DEFINITIONS}") endif() -find_package(Armadillo) include_directories(${OPENGL_INCLUDE_DIR}) if(HDF5_FOUND) include_directories(${HDF5_INCLUDE_DIR}) endif() -if(ARMADILLO_FOUND) - # Two possible values for the armadillo include dirs - include_directories(${ARMADILLO_INCLUDE_DIR} ${ARMADILLO_INCLUDE_DIRS}) -endif() include_directories(${GLFW3_INCLUDE_DIR}) # New, text rendering dependencies diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index b1953802..d032ada7 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -206,11 +206,6 @@ target_sources(showcase PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_D if(0) # During development -# -# Any example that uses sm::hexgrid or sm::cartgrid requires -# libarmadillo (because the classes use sm::BezCurve). -# -if(ARMADILLO_FOUND) # Basic mplot::Visual class example add_executable(visual visual.cpp) target_link_libraries(visual OpenGL::GL glfw Freetype::Freetype) @@ -289,7 +284,7 @@ if(ARMADILLO_FOUND) # Utility prog to test your .svg boundary files add_executable(show_svg_boundary show_svg_boundary.cpp) - target_link_libraries(show_svg_boundary ${ARMADILLO_LIBRARY} ${ARMADILLO_LIBRARIES} OpenGL::GL glfw Freetype::Freetype) + target_link_libraries(show_svg_boundary OpenGL::GL glfw Freetype::Freetype) # HexGrid::resampleImage uses an omp call that only works on Mac with # libomp, so avoid compiling this example on a Mac. @@ -316,434 +311,432 @@ if(ARMADILLO_FOUND) endif() endif(NOT APPLE) -endif(ARMADILLO_FOUND) + add_executable(helloversion helloversion.cpp) + target_link_libraries(helloversion OpenGL::GL glfw Freetype::Freetype) -add_executable(helloversion helloversion.cpp) -target_link_libraries(helloversion OpenGL::GL glfw Freetype::Freetype) + add_executable(myvisual myvisual.cpp) + target_link_libraries(myvisual OpenGL::GL glfw Freetype::Freetype) -add_executable(myvisual myvisual.cpp) -target_link_libraries(myvisual OpenGL::GL glfw Freetype::Freetype) + add_executable(grid_flat_dynamic grid_flat_dynamic.cpp) + target_link_libraries(grid_flat_dynamic OpenGL::GL glfw Freetype::Freetype) -add_executable(grid_flat_dynamic grid_flat_dynamic.cpp) -target_link_libraries(grid_flat_dynamic OpenGL::GL glfw Freetype::Freetype) + add_executable(colourmap_test colourmap_test.cpp) + target_link_libraries(colourmap_test OpenGL::GL glfw Freetype::Freetype) -add_executable(colourmap_test colourmap_test.cpp) -target_link_libraries(colourmap_test OpenGL::GL glfw Freetype::Freetype) + add_executable(colourmap_browser colourmap_browser.cpp) + target_link_libraries(colourmap_browser OpenGL::GL glfw Freetype::Freetype) -add_executable(colourmap_browser colourmap_browser.cpp) -target_link_libraries(colourmap_browser OpenGL::GL glfw Freetype::Freetype) + # grid_simple, but orthographic view is the default + add_executable(grid_ortho grid_simple.cpp) + target_compile_definitions(grid_ortho PUBLIC ORTHOGRAPHIC=1) + target_link_libraries(grid_ortho OpenGL::GL glfw Freetype::Freetype) -# grid_simple, but orthographic view is the default -add_executable(grid_ortho grid_simple.cpp) -target_compile_definitions(grid_ortho PUBLIC ORTHOGRAPHIC=1) -target_link_libraries(grid_ortho OpenGL::GL glfw Freetype::Freetype) + # similar to grid_simple but with a random value for the pixel which highlight better the different perspective + # mplot::Grid is runtime-configured + add_executable(grid_simple_rand grid_simple_rand.cpp) + target_link_libraries(grid_simple_rand OpenGL::GL glfw Freetype::Freetype) -# similar to grid_simple but with a random value for the pixel which highlight better the different perspective -# mplot::Grid is runtime-configured -add_executable(grid_simple_rand grid_simple_rand.cpp) -target_link_libraries(grid_simple_rand OpenGL::GL glfw Freetype::Freetype) + # grid_simple_rand, but orthographic view is the default + add_executable(grid_ortho_rand grid_simple_rand.cpp) + target_compile_definitions(grid_ortho_rand PUBLIC ORTHOGRAPHIC=1) + target_link_libraries(grid_ortho_rand OpenGL::GL glfw Freetype::Freetype) -# grid_simple_rand, but orthographic view is the default -add_executable(grid_ortho_rand grid_simple_rand.cpp) -target_compile_definitions(grid_ortho_rand PUBLIC ORTHOGRAPHIC=1) -target_link_libraries(grid_ortho_rand OpenGL::GL glfw Freetype::Freetype) + add_executable(grid_image grid_image.cpp) + target_link_libraries(grid_image OpenGL::GL glfw Freetype::Freetype) -add_executable(grid_image grid_image.cpp) -target_link_libraries(grid_image OpenGL::GL glfw Freetype::Freetype) + add_executable(grid_border grid_border.cpp) + target_link_libraries(grid_border OpenGL::GL glfw Freetype::Freetype) -add_executable(grid_border grid_border.cpp) -target_link_libraries(grid_border OpenGL::GL glfw Freetype::Freetype) + add_executable(grid_border2 grid_border2.cpp) + target_link_libraries(grid_border2 OpenGL::GL glfw Freetype::Freetype) -add_executable(grid_border2 grid_border2.cpp) -target_link_libraries(grid_border2 OpenGL::GL glfw Freetype::Freetype) + add_executable(grid_layout grid_layout.cpp) -add_executable(grid_layout grid_layout.cpp) + add_executable(hsvwheel hsvwheel.cpp) + target_link_libraries(hsvwheel OpenGL::GL glfw Freetype::Freetype) -add_executable(hsvwheel hsvwheel.cpp) -target_link_libraries(hsvwheel OpenGL::GL glfw Freetype::Freetype) + add_executable(cyclic_colour cyclic_colour.cpp) + target_link_libraries(cyclic_colour OpenGL::GL glfw Freetype::Freetype) -add_executable(cyclic_colour cyclic_colour.cpp) -target_link_libraries(cyclic_colour OpenGL::GL glfw Freetype::Freetype) + add_executable(colourmaps_desaturating colourmaps_desaturating.cpp) + target_link_libraries(colourmaps_desaturating OpenGL::GL glfw Freetype::Freetype) -add_executable(colourmaps_desaturating colourmaps_desaturating.cpp) -target_link_libraries(colourmaps_desaturating OpenGL::GL glfw Freetype::Freetype) + add_executable(colourmaps_other colourmaps_other.cpp) + target_link_libraries(colourmaps_other OpenGL::GL glfw Freetype::Freetype) -add_executable(colourmaps_other colourmaps_other.cpp) -target_link_libraries(colourmaps_other OpenGL::GL glfw Freetype::Freetype) + add_executable(colourmaps_crameri colourmaps_crameri.cpp) + target_link_libraries(colourmaps_crameri OpenGL::GL glfw Freetype::Freetype) -add_executable(colourmaps_crameri colourmaps_crameri.cpp) -target_link_libraries(colourmaps_crameri OpenGL::GL glfw Freetype::Freetype) + add_executable(colourmaps_cet colourmaps_cet.cpp) + target_link_libraries(colourmaps_cet OpenGL::GL glfw Freetype::Freetype) -add_executable(colourmaps_cet colourmaps_cet.cpp) -target_link_libraries(colourmaps_cet OpenGL::GL glfw Freetype::Freetype) + add_executable(colourmaps_lenthe colourmaps_lenthe.cpp) + target_link_libraries(colourmaps_lenthe OpenGL::GL glfw Freetype::Freetype) -add_executable(colourmaps_lenthe colourmaps_lenthe.cpp) -target_link_libraries(colourmaps_lenthe OpenGL::GL glfw Freetype::Freetype) + add_executable(colourmaps_matplotlib colourmaps_matplotlib.cpp) + target_link_libraries(colourmaps_matplotlib OpenGL::GL glfw Freetype::Freetype) -add_executable(colourmaps_matplotlib colourmaps_matplotlib.cpp) -target_link_libraries(colourmaps_matplotlib OpenGL::GL glfw Freetype::Freetype) + if(HAVE_STD_FORMAT) + add_executable(colourmaps_mono colourmaps_mono.cpp) + target_link_libraries(colourmaps_mono OpenGL::GL glfw Freetype::Freetype) -if(HAVE_STD_FORMAT) - add_executable(colourmaps_mono colourmaps_mono.cpp) - target_link_libraries(colourmaps_mono OpenGL::GL glfw Freetype::Freetype) + add_executable(colourmaps_hsv1d colourmaps_hsv1d.cpp) + target_link_libraries(colourmaps_hsv1d OpenGL::GL glfw Freetype::Freetype) + endif() - add_executable(colourmaps_hsv1d colourmaps_hsv1d.cpp) - target_link_libraries(colourmaps_hsv1d OpenGL::GL glfw Freetype::Freetype) -endif() + add_executable(logisticmap logisticmap.cpp) + target_link_libraries(logisticmap OpenGL::GL glfw Freetype::Freetype) -add_executable(logisticmap logisticmap.cpp) -target_link_libraries(logisticmap OpenGL::GL glfw Freetype::Freetype) + add_executable(quiver quiver.cpp) + target_link_libraries(quiver OpenGL::GL glfw Freetype::Freetype) -add_executable(quiver quiver.cpp) -target_link_libraries(quiver OpenGL::GL glfw Freetype::Freetype) + add_executable(rotating_models rotating_models.cpp) + target_link_libraries(rotating_models OpenGL::GL glfw Freetype::Freetype) -add_executable(rotating_models rotating_models.cpp) -target_link_libraries(rotating_models OpenGL::GL glfw Freetype::Freetype) + add_executable(scatter scatter.cpp) + target_link_libraries(scatter OpenGL::GL glfw Freetype::Freetype) -add_executable(scatter scatter.cpp) -target_link_libraries(scatter OpenGL::GL glfw Freetype::Freetype) + # This sphere example uses constexpr code + if(NOT APPLE) + add_executable(scatter_ico scatter_ico.cpp) + target_link_libraries(scatter_ico OpenGL::GL glfw Freetype::Freetype) -# This sphere example uses constexpr code -if(NOT APPLE) - add_executable(scatter_ico scatter_ico.cpp) - target_link_libraries(scatter_ico OpenGL::GL glfw Freetype::Freetype) + add_executable(scatter_geodesic scatter_geodesic.cpp) + target_link_libraries(scatter_geodesic OpenGL::GL glfw Freetype::Freetype) - add_executable(scatter_geodesic scatter_geodesic.cpp) - target_link_libraries(scatter_geodesic OpenGL::GL glfw Freetype::Freetype) + # Instancing also not available on Apple (limited to OpenGL 4.1) + add_executable(scatter_instanced scatter_instanced.cpp) + target_link_libraries(scatter_instanced OpenGL::GL glfw Freetype::Freetype) + add_executable(breadcrumbs breadcrumbs.cpp) + target_link_libraries(breadcrumbs OpenGL::GL glfw Freetype::Freetype) - # Instancing also not available on Apple (limited to OpenGL 4.1) - add_executable(scatter_instanced scatter_instanced.cpp) - target_link_libraries(scatter_instanced OpenGL::GL glfw Freetype::Freetype) - add_executable(breadcrumbs breadcrumbs.cpp) - target_link_libraries(breadcrumbs OpenGL::GL glfw Freetype::Freetype) + add_executable(model_crawler model_crawler.cpp) + target_link_libraries(model_crawler OpenGL::GL glfw Freetype::Freetype) + endif() - add_executable(model_crawler model_crawler.cpp) - target_link_libraries(model_crawler OpenGL::GL glfw Freetype::Freetype) -endif() + add_executable(scatter_dynamic scatter_dynamic.cpp) + target_link_libraries(scatter_dynamic OpenGL::GL glfw Freetype::Freetype) -add_executable(scatter_dynamic scatter_dynamic.cpp) -target_link_libraries(scatter_dynamic OpenGL::GL glfw Freetype::Freetype) + add_executable(duochrome duochrome.cpp) + target_link_libraries(duochrome OpenGL::GL glfw Freetype::Freetype) -add_executable(duochrome duochrome.cpp) -target_link_libraries(duochrome OpenGL::GL glfw Freetype::Freetype) + add_executable(graph1 graph1.cpp) + target_link_libraries(graph1 OpenGL::GL glfw Freetype::Freetype) -add_executable(graph1 graph1.cpp) -target_link_libraries(graph1 OpenGL::GL glfw Freetype::Freetype) + if(HAVE_STD_FORMAT) + add_executable(graph_line graph_line.cpp) + target_link_libraries(graph_line OpenGL::GL glfw Freetype::Freetype) -if(HAVE_STD_FORMAT) - add_executable(graph_line graph_line.cpp) - target_link_libraries(graph_line OpenGL::GL glfw Freetype::Freetype) + add_executable(graph_line_xcross graph_line_xcross.cpp) + target_link_libraries(graph_line_xcross OpenGL::GL glfw Freetype::Freetype) - add_executable(graph_line_xcross graph_line_xcross.cpp) - target_link_libraries(graph_line_xcross OpenGL::GL glfw Freetype::Freetype) + add_executable(graph_histo graph_histo.cpp) + target_link_libraries(graph_histo OpenGL::GL glfw Freetype::Freetype) - add_executable(graph_histo graph_histo.cpp) - target_link_libraries(graph_histo OpenGL::GL glfw Freetype::Freetype) - - add_executable(graph_distributions graph_distributions.cpp) - target_link_libraries(graph_distributions OpenGL::GL glfw Freetype::Freetype) -endif() + add_executable(graph_distributions graph_distributions.cpp) + target_link_libraries(graph_distributions OpenGL::GL glfw Freetype::Freetype) + endif() -add_executable(graph_dynamic_x2 graph_dynamic_x2.cpp) -target_link_libraries(graph_dynamic_x2 OpenGL::GL glfw Freetype::Freetype) + add_executable(graph_dynamic_x2 graph_dynamic_x2.cpp) + target_link_libraries(graph_dynamic_x2 OpenGL::GL glfw Freetype::Freetype) -add_executable(graph_fouraxes graph_fouraxes.cpp) -target_link_libraries(graph_fouraxes OpenGL::GL glfw Freetype::Freetype) + add_executable(graph_fouraxes graph_fouraxes.cpp) + target_link_libraries(graph_fouraxes OpenGL::GL glfw Freetype::Freetype) -add_executable(graph_incoming_data graph_incoming_data.cpp) -target_link_libraries(graph_incoming_data OpenGL::GL glfw Freetype::Freetype) + add_executable(graph_incoming_data graph_incoming_data.cpp) + target_link_libraries(graph_incoming_data OpenGL::GL glfw Freetype::Freetype) -add_executable(graph_incoming_data_rescale graph_incoming_data_rescale.cpp) -target_link_libraries(graph_incoming_data_rescale OpenGL::GL glfw Freetype::Freetype) + add_executable(graph_incoming_data_rescale graph_incoming_data_rescale.cpp) + target_link_libraries(graph_incoming_data_rescale OpenGL::GL glfw Freetype::Freetype) -add_executable(graph_twinax graph_twinax.cpp) -target_link_libraries(graph_twinax OpenGL::GL glfw Freetype::Freetype) + add_executable(graph_twinax graph_twinax.cpp) + target_link_libraries(graph_twinax OpenGL::GL glfw Freetype::Freetype) -add_executable(graph_rightaxis graph_rightaxis.cpp) -target_link_libraries(graph_rightaxis OpenGL::GL glfw Freetype::Freetype) + add_executable(graph_rightaxis graph_rightaxis.cpp) + target_link_libraries(graph_rightaxis OpenGL::GL glfw Freetype::Freetype) -add_executable(graph_dynamic_sine graph_dynamic_sine.cpp) -target_link_libraries(graph_dynamic_sine OpenGL::GL glfw Freetype::Freetype) + add_executable(graph_dynamic_sine graph_dynamic_sine.cpp) + target_link_libraries(graph_dynamic_sine OpenGL::GL glfw Freetype::Freetype) -add_executable(graph_dynamic_sine_rescale graph_dynamic_sine_rescale.cpp) -target_link_libraries(graph_dynamic_sine_rescale OpenGL::GL glfw Freetype::Freetype) + add_executable(graph_dynamic_sine_rescale graph_dynamic_sine_rescale.cpp) + target_link_libraries(graph_dynamic_sine_rescale OpenGL::GL glfw Freetype::Freetype) -add_executable(graph_change_xaxis graph_change_xaxis.cpp) -target_link_libraries(graph_change_xaxis OpenGL::GL glfw Freetype::Freetype) + add_executable(graph_change_xaxis graph_change_xaxis.cpp) + target_link_libraries(graph_change_xaxis OpenGL::GL glfw Freetype::Freetype) -add_executable(graph_bar graph_bar.cpp) -target_link_libraries(graph_bar OpenGL::GL glfw Freetype::Freetype) + add_executable(graph_bar graph_bar.cpp) + target_link_libraries(graph_bar OpenGL::GL glfw Freetype::Freetype) -add_executable(graph_logist graph_logist.cpp) -target_link_libraries(graph_logist OpenGL::GL glfw Freetype::Freetype) + add_executable(graph_logist graph_logist.cpp) + target_link_libraries(graph_logist OpenGL::GL glfw Freetype::Freetype) -add_executable(graph_logist2 graph_logist2.cpp) -target_link_libraries(graph_logist2 OpenGL::GL glfw Freetype::Freetype) + add_executable(graph_logist2 graph_logist2.cpp) + target_link_libraries(graph_logist2 OpenGL::GL glfw Freetype::Freetype) -add_executable(graph_coords graph_coords.cpp) -target_link_libraries(graph_coords OpenGL::GL glfw Freetype::Freetype) + add_executable(graph_coords graph_coords.cpp) + target_link_libraries(graph_coords OpenGL::GL glfw Freetype::Freetype) -add_executable(linregr linregr.cpp) -target_link_libraries(linregr OpenGL::GL glfw Freetype::Freetype) + add_executable(linregr linregr.cpp) + target_link_libraries(linregr OpenGL::GL glfw Freetype::Freetype) -# By default, the multi-context aware GLAD headers are used, so multiple windows is guaranteed to work. -add_executable(twowindows twowindows.cpp) -target_link_libraries(twowindows OpenGL::GL glfw Freetype::Freetype) + # By default, the multi-context aware GLAD headers are used, so multiple windows is guaranteed to work. + add_executable(twowindows twowindows.cpp) + target_link_libraries(twowindows OpenGL::GL glfw Freetype::Freetype) -add_executable(twowindows_mutex twowindows_mutex.cpp) -target_link_libraries(twowindows_mutex OpenGL::GL glfw Freetype::Freetype) + add_executable(twowindows_mutex twowindows_mutex.cpp) + target_link_libraries(twowindows_mutex OpenGL::GL glfw Freetype::Freetype) -add_executable(threewindows threewindows.cpp) -target_link_libraries(threewindows OpenGL::GL glfw Freetype::Freetype) + add_executable(threewindows threewindows.cpp) + target_link_libraries(threewindows OpenGL::GL glfw Freetype::Freetype) -add_executable(rod_with_normals rod_with_normals.cpp) -target_link_libraries(rod_with_normals OpenGL::GL glfw Freetype::Freetype) + add_executable(rod_with_normals rod_with_normals.cpp) + target_link_libraries(rod_with_normals OpenGL::GL glfw Freetype::Freetype) -add_executable(rod_pan rod_pan.cpp) -target_link_libraries(rod_pan OpenGL::GL glfw Freetype::Freetype) + add_executable(rod_pan rod_pan.cpp) + target_link_libraries(rod_pan OpenGL::GL glfw Freetype::Freetype) -# This example uses constexpr code -if(NOT APPLE) - add_executable(grating grating.cpp) - target_link_libraries(grating OpenGL::GL glfw Freetype::Freetype) -endif() + # This example uses constexpr code + if(NOT APPLE) + add_executable(grating grating.cpp) + target_link_libraries(grating OpenGL::GL glfw Freetype::Freetype) + endif() -add_executable(cone cone.cpp) -target_link_libraries(cone OpenGL::GL glfw Freetype::Freetype) + add_executable(cone cone.cpp) + target_link_libraries(cone OpenGL::GL glfw Freetype::Freetype) -add_executable(ring ring.cpp) -target_link_libraries(ring OpenGL::GL glfw Freetype::Freetype) + add_executable(ring ring.cpp) + target_link_libraries(ring OpenGL::GL glfw Freetype::Freetype) -# This sphere example uses constexpr code -if(NOT APPLE) - add_executable(sphere sphere.cpp) - target_link_libraries(sphere OpenGL::GL glfw Freetype::Freetype) -endif() + # This sphere example uses constexpr code + if(NOT APPLE) + add_executable(sphere sphere.cpp) + target_link_libraries(sphere OpenGL::GL glfw Freetype::Freetype) + endif() -add_executable(ellipsoid ellipsoid.cpp) -target_link_libraries(ellipsoid OpenGL::GL glfw Freetype::Freetype) + add_executable(ellipsoid ellipsoid.cpp) + target_link_libraries(ellipsoid OpenGL::GL glfw Freetype::Freetype) -# constexpr code won't work on Apple Clang -if(NOT APPLE) - add_executable(icosahedron icosahedron.cpp) - target_link_libraries(icosahedron OpenGL::GL glfw Freetype::Freetype) + # constexpr code won't work on Apple Clang + if(NOT APPLE) + add_executable(icosahedron icosahedron.cpp) + target_link_libraries(icosahedron OpenGL::GL glfw Freetype::Freetype) - add_executable(testce testce.cpp) + add_executable(testce testce.cpp) - add_executable(geodesic geodesic.cpp) - target_link_libraries(geodesic OpenGL::GL glfw Freetype::Freetype) + add_executable(geodesic geodesic.cpp) + target_link_libraries(geodesic OpenGL::GL glfw Freetype::Freetype) - add_executable(geodesic_with_normals geodesic_with_normals.cpp) - target_link_libraries(geodesic_with_normals OpenGL::GL glfw Freetype::Freetype) + add_executable(geodesic_with_normals geodesic_with_normals.cpp) + target_link_libraries(geodesic_with_normals OpenGL::GL glfw Freetype::Freetype) - add_executable(geodesic_ce geodesic_ce.cpp) - target_link_libraries(geodesic_ce OpenGL::GL glfw Freetype::Freetype) -endif() + add_executable(geodesic_ce geodesic_ce.cpp) + target_link_libraries(geodesic_ce OpenGL::GL glfw Freetype::Freetype) + endif() -add_executable(tri tri.cpp) -target_link_libraries(tri OpenGL::GL glfw Freetype::Freetype) + add_executable(tri tri.cpp) + target_link_libraries(tri OpenGL::GL glfw Freetype::Freetype) -add_executable(draw_triangles draw_triangles.cpp) -target_link_libraries(draw_triangles OpenGL::GL glfw Freetype::Freetype) + add_executable(draw_triangles draw_triangles.cpp) + target_link_libraries(draw_triangles OpenGL::GL glfw Freetype::Freetype) -add_executable(draw_triangles_intersections draw_triangles_intersections.cpp) -target_link_libraries(draw_triangles_intersections OpenGL::GL glfw Freetype::Freetype) + add_executable(draw_triangles_intersections draw_triangles_intersections.cpp) + target_link_libraries(draw_triangles_intersections OpenGL::GL glfw Freetype::Freetype) -add_executable(triangle_intersect triangle_intersect.cpp) -target_link_libraries(triangle_intersect OpenGL::GL glfw Freetype::Freetype) + add_executable(triangle_intersect triangle_intersect.cpp) + target_link_libraries(triangle_intersect OpenGL::GL glfw Freetype::Freetype) -add_executable(voronoi_random voronoi_random.cpp) -target_link_libraries(voronoi_random OpenGL::GL glfw Freetype::Freetype) + add_executable(voronoi_random voronoi_random.cpp) + target_link_libraries(voronoi_random OpenGL::GL glfw Freetype::Freetype) -add_executable(voronoi_boundary voronoi_boundary.cpp) -target_link_libraries(voronoi_boundary OpenGL::GL glfw Freetype::Freetype) + add_executable(voronoi_boundary voronoi_boundary.cpp) + target_link_libraries(voronoi_boundary OpenGL::GL glfw Freetype::Freetype) -add_executable(voronoi_rectangular voronoi_rectangular.cpp) -target_link_libraries(voronoi_rectangular OpenGL::GL glfw Freetype::Freetype) + add_executable(voronoi_rectangular voronoi_rectangular.cpp) + target_link_libraries(voronoi_rectangular OpenGL::GL glfw Freetype::Freetype) -add_executable(voronoi_vectordata voronoi_vectordata.cpp) -target_link_libraries(voronoi_vectordata OpenGL::GL glfw Freetype::Freetype) + add_executable(voronoi_vectordata voronoi_vectordata.cpp) + target_link_libraries(voronoi_vectordata OpenGL::GL glfw Freetype::Freetype) -add_executable(voronoi_function voronoi_function.cpp) -target_link_libraries(voronoi_function OpenGL::GL glfw Freetype::Freetype) + add_executable(voronoi_function voronoi_function.cpp) + target_link_libraries(voronoi_function OpenGL::GL glfw Freetype::Freetype) -add_executable(voronoi_function_flat voronoi_function_flat.cpp) -target_link_libraries(voronoi_function_flat OpenGL::GL glfw Freetype::Freetype) + add_executable(voronoi_function_flat voronoi_function_flat.cpp) + target_link_libraries(voronoi_function_flat OpenGL::GL glfw Freetype::Freetype) -add_executable(voronoi_fixed voronoi_fixed.cpp) -target_link_libraries(voronoi_fixed OpenGL::GL glfw Freetype::Freetype) + add_executable(voronoi_fixed voronoi_fixed.cpp) + target_link_libraries(voronoi_fixed OpenGL::GL glfw Freetype::Freetype) -add_executable(voronoi_fixed_xz voronoi_fixed_xz.cpp) -target_link_libraries(voronoi_fixed_xz OpenGL::GL glfw Freetype::Freetype) + add_executable(voronoi_fixed_xz voronoi_fixed_xz.cpp) + target_link_libraries(voronoi_fixed_xz OpenGL::GL glfw Freetype::Freetype) -add_executable(voronoi_fixed_nearlyz voronoi_fixed_nearlyz.cpp) -target_link_libraries(voronoi_fixed_nearlyz OpenGL::GL glfw Freetype::Freetype) + add_executable(voronoi_fixed_nearlyz voronoi_fixed_nearlyz.cpp) + target_link_libraries(voronoi_fixed_nearlyz OpenGL::GL glfw Freetype::Freetype) -add_executable(rectangle rectangle.cpp) -target_link_libraries(rectangle OpenGL::GL glfw Freetype::Freetype) + add_executable(rectangle rectangle.cpp) + target_link_libraries(rectangle OpenGL::GL glfw Freetype::Freetype) -add_executable(rhombo rhombo.cpp) -target_link_libraries(rhombo OpenGL::GL glfw Freetype::Freetype) + add_executable(rhombo rhombo.cpp) + target_link_libraries(rhombo OpenGL::GL glfw Freetype::Freetype) -add_executable(rhombo_scene rhombo_scene.cpp) -target_link_libraries(rhombo_scene OpenGL::GL glfw Freetype::Freetype) + add_executable(rhombo_scene rhombo_scene.cpp) + target_link_libraries(rhombo_scene OpenGL::GL glfw Freetype::Freetype) -add_executable(rhombo_scene2 rhombo_scene2.cpp) -target_link_libraries(rhombo_scene2 OpenGL::GL glfw Freetype::Freetype) + add_executable(rhombo_scene2 rhombo_scene2.cpp) + target_link_libraries(rhombo_scene2 OpenGL::GL glfw Freetype::Freetype) -add_executable(cube cube.cpp) -target_link_libraries(cube OpenGL::GL glfw Freetype::Freetype) + add_executable(cube cube.cpp) + target_link_libraries(cube OpenGL::GL glfw Freetype::Freetype) -# Eigen finding is not reliable on Github Mac OS runners -if(NOT APPLE) - if(Eigen3_FOUND) - add_executable(cubetrans cubetrans.cpp) - target_include_directories (cubetrans BEFORE PRIVATE ${EIGEN3_INCLUDE_DIR}) - target_link_libraries(cubetrans OpenGL::GL glfw Freetype::Freetype) - endif(Eigen3_FOUND) -endif() + # Eigen finding is not reliable on Github Mac OS runners + if(NOT APPLE) + if(Eigen3_FOUND) + add_executable(cubetrans cubetrans.cpp) + target_include_directories (cubetrans BEFORE PRIVATE ${EIGEN3_INCLUDE_DIR}) + target_link_libraries(cubetrans OpenGL::GL glfw Freetype::Freetype) + endif(Eigen3_FOUND) + endif() -add_executable(cubetrans2 cubetrans2.cpp) -target_link_libraries(cubetrans2 OpenGL::GL glfw Freetype::Freetype) + add_executable(cubetrans2 cubetrans2.cpp) + target_link_libraries(cubetrans2 OpenGL::GL glfw Freetype::Freetype) -add_executable(quads quads.cpp) -target_link_libraries(quads OpenGL::GL glfw Freetype::Freetype) + add_executable(quads quads.cpp) + target_link_libraries(quads OpenGL::GL glfw Freetype::Freetype) -add_executable(quadsmesh quads.cpp) -target_compile_definitions(quadsmesh PUBLIC MESH=1) -target_link_libraries(quadsmesh OpenGL::GL glfw Freetype::Freetype) + add_executable(quadsmesh quads.cpp) + target_compile_definitions(quadsmesh PUBLIC MESH=1) + target_link_libraries(quadsmesh OpenGL::GL glfw Freetype::Freetype) -add_executable(pointrows pointrows.cpp) -target_link_libraries(pointrows OpenGL::GL glfw Freetype::Freetype) + add_executable(pointrows pointrows.cpp) + target_link_libraries(pointrows OpenGL::GL glfw Freetype::Freetype) -add_executable(pointrows_mesh pointrows.cpp) -target_compile_definitions(pointrows_mesh PUBLIC MESH=1) -target_link_libraries(pointrows_mesh OpenGL::GL glfw Freetype::Freetype) + add_executable(pointrows_mesh pointrows.cpp) + target_compile_definitions(pointrows_mesh PUBLIC MESH=1) + target_link_libraries(pointrows_mesh OpenGL::GL glfw Freetype::Freetype) -add_executable(jsonconfig jsonconfig.cpp) -target_link_libraries(jsonconfig) + add_executable(jsonconfig jsonconfig.cpp) + target_link_libraries(jsonconfig) -add_executable(randvec randvec.cpp) -target_link_libraries(randvec OpenGL::GL glfw Freetype::Freetype) + add_executable(randvec randvec.cpp) + target_link_libraries(randvec OpenGL::GL glfw Freetype::Freetype) -# Demo of sm::math's bootstrap implementation -add_executable(bootstrap bootstrap.cpp) -target_link_libraries(bootstrap OpenGL::GL glfw Freetype::Freetype) + # Demo of sm::math's bootstrap implementation + add_executable(bootstrap bootstrap.cpp) + target_link_libraries(bootstrap OpenGL::GL glfw Freetype::Freetype) -add_executable(vvec_convolve vvec_convolve.cpp) -target_link_libraries(vvec_convolve OpenGL::GL glfw Freetype::Freetype) + add_executable(vvec_convolve vvec_convolve.cpp) + target_link_libraries(vvec_convolve OpenGL::GL glfw Freetype::Freetype) -add_executable(vvec_gauss vvec_gauss.cpp) -target_link_libraries(vvec_gauss OpenGL::GL glfw Freetype::Freetype) + add_executable(vvec_gauss vvec_gauss.cpp) + target_link_libraries(vvec_gauss OpenGL::GL glfw Freetype::Freetype) -add_executable(vvec_rgb_gaussians vvec_rgb_gaussians.cpp) -target_link_libraries(vvec_rgb_gaussians OpenGL::GL glfw Freetype::Freetype) + add_executable(vvec_rgb_gaussians vvec_rgb_gaussians.cpp) + target_link_libraries(vvec_rgb_gaussians OpenGL::GL glfw Freetype::Freetype) -add_executable(vvec_smoothgauss vvec_smoothgauss.cpp) -target_link_libraries(vvec_smoothgauss OpenGL::GL glfw Freetype::Freetype) + add_executable(vvec_smoothgauss vvec_smoothgauss.cpp) + target_link_libraries(vvec_smoothgauss OpenGL::GL glfw Freetype::Freetype) -add_executable(quit_callback quit_callback.cpp) -target_link_libraries(quit_callback OpenGL::GL glfw Freetype::Freetype) + add_executable(quit_callback quit_callback.cpp) + target_link_libraries(quit_callback OpenGL::GL glfw Freetype::Freetype) -add_executable(izhikevich izhikevich.cpp) -target_link_libraries(izhikevich OpenGL::GL glfw Freetype::Freetype) + add_executable(izhikevich izhikevich.cpp) + target_link_libraries(izhikevich OpenGL::GL glfw Freetype::Freetype) -add_executable(izhikevich_alt izhikevich_alt.cpp) -target_link_libraries(izhikevich_alt OpenGL::GL glfw Freetype::Freetype) + add_executable(izhikevich_alt izhikevich_alt.cpp) + target_link_libraries(izhikevich_alt OpenGL::GL glfw Freetype::Freetype) -add_executable(curvytelly curvytelly.cpp) -target_link_libraries(curvytelly OpenGL::GL glfw Freetype::Freetype) + add_executable(curvytelly curvytelly.cpp) + target_link_libraries(curvytelly OpenGL::GL glfw Freetype::Freetype) -add_executable(curvytelly_pipe curvytelly_pipe.cpp) -target_link_libraries(curvytelly_pipe OpenGL::GL glfw Freetype::Freetype) + add_executable(curvytelly_pipe curvytelly_pipe.cpp) + target_link_libraries(curvytelly_pipe OpenGL::GL glfw Freetype::Freetype) -add_executable(curvytelly_chequered_pipe curvytelly_chequered_pipe.cpp) -target_link_libraries(curvytelly_chequered_pipe OpenGL::GL glfw Freetype::Freetype) + add_executable(curvytelly_chequered_pipe curvytelly_chequered_pipe.cpp) + target_link_libraries(curvytelly_chequered_pipe OpenGL::GL glfw Freetype::Freetype) -add_executable(lighting_test lighting_test.cpp) -target_link_libraries(lighting_test OpenGL::GL glfw Freetype::Freetype) + add_executable(lighting_test lighting_test.cpp) + target_link_libraries(lighting_test OpenGL::GL glfw Freetype::Freetype) -add_executable(healpix healpix.cpp) -target_link_libraries(healpix OpenGL::GL glfw Freetype::Freetype) + add_executable(healpix healpix.cpp) + target_link_libraries(healpix OpenGL::GL glfw Freetype::Freetype) -add_executable(lines lines.cpp) -target_link_libraries(lines OpenGL::GL glfw Freetype::Freetype) + add_executable(lines lines.cpp) + target_link_libraries(lines OpenGL::GL glfw Freetype::Freetype) -add_executable(line line.cpp) -target_link_libraries(line OpenGL::GL glfw Freetype::Freetype) + add_executable(line line.cpp) + target_link_libraries(line OpenGL::GL glfw Freetype::Freetype) -add_executable(txt txt.cpp) -target_link_libraries(txt OpenGL::GL glfw Freetype::Freetype) -target_compile_definitions(txt PUBLIC GLAD_OPTION_MX=1) + add_executable(txt txt.cpp) + target_link_libraries(txt OpenGL::GL glfw Freetype::Freetype) + target_compile_definitions(txt PUBLIC GLAD_OPTION_MX=1) -add_executable(maketicks maketicks.cpp) + add_executable(maketicks maketicks.cpp) -add_executable(coordarrows coordarrows.cpp) -target_link_libraries(coordarrows OpenGL::GL glfw Freetype::Freetype) + add_executable(coordarrows coordarrows.cpp) + target_link_libraries(coordarrows OpenGL::GL glfw Freetype::Freetype) -add_executable(frames frames.cpp) -target_link_libraries(frames OpenGL::GL glfw Freetype::Freetype) + add_executable(frames frames.cpp) + target_link_libraries(frames OpenGL::GL glfw Freetype::Freetype) -add_executable(sph_to_cart sph_to_cart.cpp) -target_link_libraries(sph_to_cart OpenGL::GL glfw Freetype::Freetype) + add_executable(sph_to_cart sph_to_cart.cpp) + target_link_libraries(sph_to_cart OpenGL::GL glfw Freetype::Freetype) -add_executable(polar polar.cpp) -target_link_libraries(polar OpenGL::GL glfw Freetype::Freetype) + add_executable(polar polar.cpp) + target_link_libraries(polar OpenGL::GL glfw Freetype::Freetype) -if(HAVE_STD_FORMAT) - add_executable(zernike_radial zernike_radial.cpp) - target_link_libraries(zernike_radial OpenGL::GL glfw Freetype::Freetype) + if(HAVE_STD_FORMAT) + add_executable(zernike_radial zernike_radial.cpp) + target_link_libraries(zernike_radial OpenGL::GL glfw Freetype::Freetype) - add_executable(zernike zernike.cpp) - target_link_libraries(zernike OpenGL::GL glfw Freetype::Freetype) + add_executable(zernike zernike.cpp) + target_link_libraries(zernike OpenGL::GL glfw Freetype::Freetype) - add_executable(vonmises vonmises.cpp) - target_link_libraries(vonmises OpenGL::GL glfw Freetype::Freetype) -endif() + add_executable(vonmises vonmises.cpp) + target_link_libraries(vonmises OpenGL::GL glfw Freetype::Freetype) + endif() -add_executable(show_boundingboxes show_boundingboxes.cpp) -target_link_libraries(show_boundingboxes OpenGL::GL glfw Freetype::Freetype) + add_executable(show_boundingboxes show_boundingboxes.cpp) + target_link_libraries(show_boundingboxes OpenGL::GL glfw Freetype::Freetype) -# if have compound-ray header -add_executable(cray_eye cray_eye.cpp) -target_link_libraries(cray_eye OpenGL::GL glfw Freetype::Freetype) + # if have compound-ray header + add_executable(cray_eye cray_eye.cpp) + target_link_libraries(cray_eye OpenGL::GL glfw Freetype::Freetype) -if(ARMADILLO_FOUND) - # Make use of principle component analysis from arma in this example - add_executable(ellipse_pca ellipse_pca.cpp) - target_link_libraries(ellipse_pca ${ARMADILLO_LIBRARY} ${ARMADILLO_LIBRARIES} OpenGL::GL glfw Freetype::Freetype) -endif() + if(0) + # I made use of principle component analysis from arma in this example. + add_executable(ellipse_pca ellipse_pca.cpp) + target_link_libraries(ellipse_pca ${ARMADILLO_LIBRARY} ${ARMADILLO_LIBRARIES} OpenGL::GL glfw Freetype::Freetype) + endif() -add_executable(trace_boundary trace_boundary.cpp) -target_link_libraries(trace_boundary OpenGL::GL glfw Freetype::Freetype) + add_executable(trace_boundary trace_boundary.cpp) + target_link_libraries(trace_boundary OpenGL::GL glfw Freetype::Freetype) -# Shader compute examples. Not supported on Apple, which is limited to -# OpenGL 4.1 or Windows because I want to keep the GL header inclusion -# simple on these examples. -if(NOT APPLE AND NOT WIN32) - add_subdirectory(gl_compute) -endif() + # Shader compute examples. Not supported on Apple, which is limited to + # OpenGL 4.1 or Windows because I want to keep the GL header inclusion + # simple on these examples. + if(NOT APPLE AND NOT WIN32) + add_subdirectory(gl_compute) + endif() -# Examples showing how to use mathplot with Qt. Compiled only if -# find_package found Qt5 -if(Qt5_FOUND) - add_subdirectory(qt) -endif() + # Examples showing how to use mathplot with Qt. Compiled only if + # find_package found Qt5 + if(Qt5_FOUND) + add_subdirectory(qt) + endif() -# Disabled as haven't figured out a GL multi-context scheme for wx windows -#if(wxWidgets_FOUND) -# add_subdirectory(wx) -#endif() + # Disabled as haven't figured out a GL multi-context scheme for wx windows + #if(wxWidgets_FOUND) + # add_subdirectory(wx) + #endif() -if (OpenGL_EGL_FOUND) - add_subdirectory(pi) -endif() + if (OpenGL_EGL_FOUND) + add_subdirectory(pi) + endif() -# Screenshots used in the documentation/reference website -if(BUILD_DOC_SCREENSHOTS) - add_subdirectory(docs) -endif() + # Screenshots used in the documentation/reference website + if(BUILD_DOC_SCREENSHOTS) + add_subdirectory(docs) + endif() endif(0) diff --git a/examples/pi/CMakeLists.txt b/examples/pi/CMakeLists.txt index 1b55e9b1..5fd52fef 100644 --- a/examples/pi/CMakeLists.txt +++ b/examples/pi/CMakeLists.txt @@ -5,13 +5,11 @@ # Ensure we can #include include_directories(BEFORE ${PROJECT_SOURCE_DIR}) -if(ARMADILLO_FOUND) - add_executable(convolve_pi convolve.cpp) - target_link_libraries(convolve_pi OpenGL::EGL glfw Freetype::Freetype) +add_executable(convolve_pi convolve.cpp) +target_link_libraries(convolve_pi OpenGL::EGL glfw Freetype::Freetype) - add_executable(hexgrid_pi hexgrid.cpp) - target_link_libraries(hexgrid_pi OpenGL::EGL glfw Freetype::Freetype) -endif(ARMADILLO_FOUND) +add_executable(hexgrid_pi hexgrid.cpp) +target_link_libraries(hexgrid_pi OpenGL::EGL glfw Freetype::Freetype) add_executable(graph1_pi graph1.cpp) target_link_libraries(graph1_pi OpenGL::EGL glfw Freetype::Freetype) diff --git a/examples/qt/fps/CMakeLists.txt b/examples/qt/fps/CMakeLists.txt index 25646038..76ba3106 100644 --- a/examples/qt/fps/CMakeLists.txt +++ b/examples/qt/fps/CMakeLists.txt @@ -1,5 +1,3 @@ -if(ARMADILLO_FOUND) - add_executable(qtfps main.cpp mainwindow.cpp) - target_compile_definitions(qtfps PUBLIC GL3_PROTOTYPES GL_GLEXT_PROTOTYPES) - target_link_libraries(qtfps Qt5::Gui Qt5::Widgets Qt5::Core ${MPLOT_LIBS_CORE} ${MPLOT_LIBS_GL}) -endif(ARMADILLO_FOUND) +add_executable(qtfps main.cpp mainwindow.cpp) +target_compile_definitions(qtfps PUBLIC GL3_PROTOTYPES GL_GLEXT_PROTOTYPES) +target_link_libraries(qtfps Qt5::Gui Qt5::Widgets Qt5::Core ${MPLOT_LIBS_CORE} ${MPLOT_LIBS_GL}) diff --git a/examples/qt/hexgrid/CMakeLists.txt b/examples/qt/hexgrid/CMakeLists.txt index ca719d6f..31e65a66 100644 --- a/examples/qt/hexgrid/CMakeLists.txt +++ b/examples/qt/hexgrid/CMakeLists.txt @@ -1,5 +1,3 @@ -if(ARMADILLO_FOUND) - add_executable(qthexgrid main.cpp mainwindow.cpp) - target_compile_definitions(qthexgrid PUBLIC GL3_PROTOTYPES GL_GLEXT_PROTOTYPES) - target_link_libraries(qthexgrid Qt5::Gui Qt5::Widgets Qt5::Core ${MPLOT_LIBS_CORE} ${MPLOT_LIBS_GL}) -endif(ARMADILLO_FOUND) +add_executable(qthexgrid main.cpp mainwindow.cpp) +target_compile_definitions(qthexgrid PUBLIC GL3_PROTOTYPES GL_GLEXT_PROTOTYPES) +target_link_libraries(qthexgrid Qt5::Gui Qt5::Widgets Qt5::Core ${MPLOT_LIBS_CORE} ${MPLOT_LIBS_GL}) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2a0db1bf..68f2483d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,45 +3,36 @@ # All #includes in test programs have to be #include "mplot/header.h" include_directories(BEFORE ${PROJECT_SOURCE_DIR}) -if(ARMADILLO_FOUND) - - # Test reading trial.svg - set(TARGETTEST3 testreadcurves) - set(SOURCETEST3 testreadcurves.cpp) - add_executable(${TARGETTEST3} ${SOURCETEST3}) - target_link_libraries(${TARGETTEST3} ${ARMADILLO_LIBRARY} ${ARMADILLO_LIBRARIES}) - add_test(testreadcurves ${TARGETTEST3}) - - # Test reading whiskerbarrels_withcentres.svg - set(TARGETTEST31 testreadcurves_circles) - set(SOURCETEST31 testreadcurves_circles.cpp) - add_executable(${TARGETTEST31} ${SOURCETEST31}) - target_link_libraries(${TARGETTEST31} ${ARMADILLO_LIBRARY} ${ARMADILLO_LIBRARIES}) - add_test(testreadcurves_circles ${TARGETTEST31}) - -endif(ARMADILLO_FOUND) +# Test reading trial.svg +set(TARGETTEST3 testreadcurves) +set(SOURCETEST3 testreadcurves.cpp) +add_executable(${TARGETTEST3} ${SOURCETEST3}) +add_test(testreadcurves ${TARGETTEST3}) + +# Test reading whiskerbarrels_withcentres.svg +set(TARGETTEST31 testreadcurves_circles) +set(SOURCETEST31 testreadcurves_circles.cpp) +add_executable(${TARGETTEST31} ${SOURCETEST31}) +add_test(testreadcurves_circles ${TARGETTEST31}) if(${glfw3_FOUND}) - if(ARMADILLO_FOUND) - # Test hexgrid3 (hexgrid2 with visualisation) - add_executable(testhexgrid3 testhexgrid3.cpp) - target_link_libraries(testhexgrid3 ${ARMADILLO_LIBRARY} ${ARMADILLO_LIBRARIES} OpenGL::GL glfw Freetype::Freetype) + # Test hexgrid3 (hexgrid2 with visualisation) + add_executable(testhexgrid3 testhexgrid3.cpp) + target_link_libraries(testhexgrid3 OpenGL::GL glfw Freetype::Freetype) - if(HDF5_FOUND) - # Test hexgridsave (HexGrid's save feature) - add_executable(testhexgridsave testhexgridsave.cpp) - target_link_libraries(testhexgridsave ${ARMADILLO_LIBRARY} ${ARMADILLO_LIBRARIES} ${HDF5_C_LIBRARIES} OpenGL::GL glfw Freetype::Freetype) - endif(HDF5_FOUND) + if(HDF5_FOUND) + # Test hexgridsave (HexGrid's save feature) + add_executable(testhexgridsave testhexgridsave.cpp) + target_link_libraries(testhexgridsave ${HDF5_C_LIBRARIES} OpenGL::GL glfw Freetype::Freetype) + endif(HDF5_FOUND) - add_executable(testbighexgrid testbighexgrid.cpp) - target_link_libraries(testbighexgrid OpenGL::GL glfw Freetype::Freetype) + add_executable(testbighexgrid testbighexgrid.cpp) + target_link_libraries(testbighexgrid OpenGL::GL glfw Freetype::Freetype) - add_executable(testbezderiv3 testbezderiv3.cpp) - target_compile_definitions(testbezderiv3 PUBLIC FLT=double) - target_link_libraries(testbezderiv3 ${ARMADILLO_LIBRARY} ${ARMADILLO_LIBRARIES} OpenGL::GL glfw Freetype::Freetype) - add_test(testbezderiv3 testbezderiv3) - - endif(ARMADILLO_FOUND) + add_executable(testbezderiv3 testbezderiv3.cpp) + target_compile_definitions(testbezderiv3 PUBLIC FLT=double) + target_link_libraries(testbezderiv3 OpenGL::GL glfw Freetype::Freetype) + add_test(testbezderiv3 testbezderiv3) add_executable(testVisCoordArrows testVisCoordArrows.cpp) target_link_libraries(testVisCoordArrows OpenGL::GL glfw Freetype::Freetype) @@ -49,16 +40,13 @@ if(${glfw3_FOUND}) add_executable(testVisRemoveModel testVisRemoveModel.cpp) target_link_libraries(testVisRemoveModel OpenGL::GL glfw Freetype::Freetype) - if(ARMADILLO_FOUND) - # Test elliptical HexGrid code (visualized with mplot::Visual) - add_executable(test_ellipseboundary test_ellipseboundary.cpp) - target_link_libraries(test_ellipseboundary OpenGL::GL glfw Freetype::Freetype) - - # Test circular HexGrid code - add_executable(test_circleboundary test_circleboundary.cpp) - target_link_libraries(test_circleboundary OpenGL::GL glfw Freetype::Freetype) - endif(ARMADILLO_FOUND) + # Test elliptical HexGrid code (visualized with mplot::Visual) + add_executable(test_ellipseboundary test_ellipseboundary.cpp) + target_link_libraries(test_ellipseboundary OpenGL::GL glfw Freetype::Freetype) + # Test circular HexGrid code + add_executable(test_circleboundary test_circleboundary.cpp) + target_link_libraries(test_circleboundary OpenGL::GL glfw Freetype::Freetype) endif() # Test the colour mapping From 15e2e56f23d82511af3e769b36adee4818f798af Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 12 Mar 2026 21:58:48 +0000 Subject: [PATCH 060/106] Updates to readmes with removal of armadillo --- README.build.linux.md | 29 ++++++++++++------------- README.build.mac.md | 49 +++++-------------------------------------- README.cmake.md | 14 ++++++------- README.md | 4 ++-- 4 files changed, 27 insertions(+), 69 deletions(-) diff --git a/README.build.linux.md b/README.build.linux.md index a2bf4aef..6e39a6d6 100644 --- a/README.build.linux.md +++ b/README.build.linux.md @@ -12,24 +12,23 @@ program and a C++ compiler which can compile c++-20 code. ## *Required*: Install dependencies -mathplot code depends on OpenGL, Freetype and glfw3. Armadillo and HDF5 are optional dependencies which you may need. Armadillo is required if you use the `sm::bezcurve` class or any of the classes `sm::hexgrid`/`mplot::ReadCurve`/`sm::cartgri`d (which all use `sm::bezcurvepath` and hence `sm::bezcurve`). HDF5 is required if you use the `sm::hdfdata` wrapper class, or if you want to compile `sm::hexgrid`/`sm::cartgrid` with built-in `save()` and `load()` functions. +mathplot code depends on OpenGL, Freetype and glfw3. HDF5 is an optional dependency which you may need. HDF5 is required if you use the `sm::hdfdata` wrapper class, or if you want to compile the `hexgrid_hdf` module which provides `save()` and `load()` functions. ### Package-managed dependencies for Ubuntu/Debian To install the visualization dependencies on Ubuntu or Debian Linux: ```sh -sudo apt install build-essential cmake git \ - nlohmann-json3-dev librapidxml-dev \ +sudo apt install build-essential cmake ninja git \ + librapidxml-dev \ freeglut3-dev libglu1-mesa-dev libxmu-dev libxi-dev \ libglfw3-dev libfreetype-dev - +# nlohmann-json3-dev was removed as I have to bundle a very up to date version for C++ modules support ``` For the optional dependencies it's: ```sh -sudo apt install libarmadillo-dev libhdf5-dev qtcreator qtbase5-dev libwxgtk3.2-dev libegl-dev libgbm-dev +sudo apt install libhdf5-dev qtcreator qtbase5-dev libwxgtk3.2-dev libegl-dev libgbm-dev ``` -* Armadillo. Only required if you use the ```sm::bezcurve``` class. * HDF5 library. Required if you use the wrapper class ```sm::hdfdata``` or any of the classes that make use of `sm::hdfdata` (```sm::hexgrid```,```sm::cartgrid```,```sm::anneal```). Their tests and examples should all compile if the libraries are detected and be omitted if not. * Qt library. Installing qtcreator will bring in the Qt5 libraries that are used to compile some Qt-mathplot example programs. It almost certainly possible to install *only* the Qt5 Core, Gui and Widgets libraries, but that hasn't been verified. On recent Ubuntu systems, you may well need qtbase5-dev to get the cmake scripts to `find_package(Qt5...)`. * WxWindows. libwxgtk3.2-dev (you'll need Ubuntu 23.04+) will enable the compilation of mathplot-wxWidgets example programs. @@ -38,18 +37,16 @@ sudo apt install libarmadillo-dev libhdf5-dev qtcreator qtbase5-dev libwxgtk3.2- ### Package-managed dependencies for Arch Linux -On Arch Linux, all required dependencies except Armadillo are available in the official repository. They can be installed as follows: +On Arch Linux, all required dependencies are available in the official repository. They can be installed as follows: ```shell -sudo pacman -S vtk lapack blas freeglut glfw-wayland nlohmann-json +sudo pacman -S vtk lapack blas freeglut glfw-wayland # nlohmann-json # Optional: sudo pacman -S hdf5 ``` **Note:** Specify `glfw-x11` instead of `glfw-wayland` if you use X.org. -Then, optionally, install [Armadillo](https://aur.archlinux.org/packages/armadillo/) from AUR. - ## *Optional*: Build mathplot examples or tests To build the mathplot example programs, it's the usual CMake process: @@ -60,18 +57,18 @@ git clone https://github.com/sebsjames/mathplot.git cd mathplot mkdir build cd build -cmake .. -make -j$(nproc) +cmake .. -GNinja +ninja # I usually place the mathplot directory inside the code repository I'm working # on, I call this 'in-tree mathplot', but you can also have the headers in # /usr/local/include (control location with the usual CMAKE_INSTALL_PREFIX) if you install: -# sudo make install +# sudo ninja install ``` ### Building test programs (or NOT building the examples) -By default, the example programs are built with the call to `make`, but unit test programs are not. To build test programs, and control whether example programs are compiled, use the cmake flags `BUILD_TESTS` and `BUILD_EXAMPLES`, changing your cmake line to: +By default, the example programs are built with the call to `ninja`, but unit test programs are not. To build test programs, and control whether example programs are compiled, use the cmake flags `BUILD_TESTS` and `BUILD_EXAMPLES`, changing your cmake line to: ```sh -cmake .. -DBUILD_TESTS=ON -DBUILD_EXAMPLES=OFF # Build tests but not examples +cmake .. -GNinja -DBUILD_TESTS=ON -DBUILD_EXAMPLES=OFF # Build tests but not examples # ...etc ``` @@ -82,7 +79,7 @@ as g++-11 or clang, then you just change the cmake call in the recipe above. It becomes: ```sh -CXX=g++-11 cmake .. -DBUILD_TESTS=ON +CXX=g++-16 cmake .. -DBUILD_TESTS=ON ``` To run the test suite, use the `ctest` command in the build directory or `make test`. diff --git a/README.build.mac.md b/README.build.mac.md index 7d142b8c..5eb50582 100644 --- a/README.build.mac.md +++ b/README.build.mac.md @@ -49,7 +49,7 @@ command line tools, then install the Mac ports installation package. Finally, use Mac ports to install the rest of the dependencies: ```sh -sudo port install cmake armadillo nlohmann-json +sudo port install cmake ``` *Be aware that if you have conflicting versions of any of the @@ -63,8 +63,7 @@ compile glfw3 by hand. It's much cleaner to build each of the dependencies by hand. That means first installing cmake, which I do with a binary package from -https://cmake.org/download/, and then compiling hdf5 and -armadillo (all of which support a cmake build process). +https://cmake.org/download/, and then compiling hdf5. After downloading and installing cmake using the MacOS installer, I add these lines to ~/.zprofile so that I can type cmake at the terminal: @@ -80,31 +79,8 @@ The mathplot github actions for mac runners use brew to install dependencies. The command for the basic dependencies is ```sh -brew install libomp glfw armadillo hdf5 nlohmann-json -``` - -#### Armadillo - -Armadillo is a library for matrix manipulation. The only place it's used in -mathplot is within the Bezier curve code, -sm::bezcurve. This code is used in the sm::hexgrid classes. If your programs won't use Bezier curve code, then you don't need Armadillo. It *is* required to compile some of mathplot's test programs though. - -Download a package - I downloaded -armadillo-9.900.3.tar.xz, though older versions back to 8.400.0 should -work. - -```sh -mkdir -p ~/src -cd ~/src -tar xvf path/to/downloaded/armadillo-9.900.3.tar.xz -cd armadillo-9.900.3 -mkdir build -cd build -cmake .. -# or optionally: cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_OSX_DEPLOYMENT_TARGET=10.14 -# which will set the install locn and get the code compiled for targets as old as mac 10.14 -make -sudo make install +brew install libomp glfw hdf5 # nlohmann-json +# nlohmann-json was removed as I have to bundle a very up to date version for C++ modules support ``` #### HDF5 @@ -133,8 +109,7 @@ If present, the Qt5 components Core, Gui and Widgets components are used to comp ### Common manual dependency builds -Whether or not you used mac ports to install hdf5 and -armadillo, glfw3 also needs to be built separately (I've not investigated +Whether or not you used mac ports to install hdf5, glfw3 also needs to be built separately (I've not investigated whether there is a mac ports version of glfw). #### glfw3 @@ -153,20 +128,6 @@ make sudo make install ``` -#### nlohmann json - -You'll need a package of nlohmann json. - -```sh -sudo brew install nlohmann-json -``` -```sh -sudo port install nlohmann-json -``` - -Or install manually from https://github.com/nlohmann/json - - ## Build mathplot on Mac To build mathplot itself, it's the usual CMake process: diff --git a/README.cmake.md b/README.cmake.md index 85dd826b..06b78953 100644 --- a/README.cmake.md +++ b/README.cmake.md @@ -1,10 +1,12 @@ # Building your code with mathplot +These instructions will be a little out of date now we build with C++ 20 modules. + ## Dependencies -First, ensure you have the necessary dependencies installed. Classes in mathplot use nlohmann-json, rapidxml, Armadillo, OpenGL, Freetype, glfw3 and HDF5. +First, ensure you have the necessary dependencies installed. Classes in mathplot use nlohmann-json (submoduled), rapidxml, OpenGL, Freetype, glfw3 and HDF5. You won't necessarily need all of these; it depends on which classes you will use (see [here](https://github.com/sebsjames/mathplot/blob/main/README.coding.md#linking-a-mathplot-program) for details). -For most visualisation, you only need OpenGL, Freetype and glfw3 and the header files for nlohmann-json. +For most visualisation, you only need OpenGL, Freetype and glfw3. Platform-specific instructions can be found in the files [README.build.linux.md](https://github.com/sebsjames/mathplot/blob/main/README.build.linux.md), [README.build.mac.md](https://github.com/sebsjames/mathplot/blob/main/README.build.mac.md) and [README.build.windows.md](https://github.com/sebsjames/mathplot/blob/main/README.build.windows.md). ## Three necessities to build @@ -15,7 +17,7 @@ to tell it: **1**) What compiler flags to add to the compiler command line, including a directive to say where the fonts that mathplot will compile into your binaries (if you're using mplot::Visual) are located. **2**) Where the mathplot headers (in *mplot/*) are -to be found. **3**) which libraries to link to. +to be found. **3**) which modules to build and which libraries to link to. While you can install mathplot headers (and fonts) into a chosen location (/usr/local by default) we recommend that you just clone a @@ -75,14 +77,12 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMPLOT_FONTS_DIR=\"\\\"/usr/local/share ```cmake # Find the libraries which will be needed find_package(HDF5 REQUIRED) # Only required if you used sm::hdfdata -find_package(Armadillo REQUIRED) # Only required if you use the sm::bezcurve classes or sm::hexgrid/sm::cartgrid find_package(OpenGL REQUIRED) # This, glfw3, Freetype and nlohmann-json are required for mplot::Visual find_package(glfw3 3.3 REQUIRED) find_package(Freetype REQUIRED) -find_package(nlohmann-json REQUIRED) # Define collections of includes for the dependencies -set(MPLOT_INC_CORE ${ARMADILLO_INCLUDE_DIR} ${ARMADILLO_INCLUDE_DIRS} ${HDF5_INCLUDE_DIR}) +set(MPLOT_INC_CORE ${HDF5_INCLUDE_DIR}) set(MPLOT_INC_GL ${OPENGL_INCLUDE_DIR} ${GLFW3_INCLUDE_DIR} ${FREETYPE_INCLUDE_DIRS}) include_directories(${MPLOT_INC_CORE} ${MPLOT_INC_GL}) @@ -104,7 +104,7 @@ classes you use from mathplot, you'll need to link to some or all of these: ```cmake -set(MPLOT_LIBS_CORE ${ARMADILLO_LIBRARY} ${ARMADILLO_LIBRARIES} ${HDF5_C_LIBRARIES}) +set(MPLOT_LIBS_CORE ${HDF5_C_LIBRARIES}) set(MPLOT_LIBS_GL OpenGL::GL Freetype::Freetype glfw) target_link_libraries(myprogtarget ${MPLOT_LIBS_CORE} ${MPLOT_LIBS_GL}) ``` diff --git a/README.md b/README.md index 6e74ab23..c2df36d7 100644 --- a/README.md +++ b/README.md @@ -33,10 +33,10 @@ This quick start shows dependency installation for Linux, because on this platfo ```bash # Install dependencies for building graph1.cpp and (almost) all the other examples (assuming Debian-like OS) -sudo apt install build-essential cmake git wget ninja-build \ +sudo apt install build-essential cmake git ninja-build \ nlohmann-json3-dev librapidxml-dev \ freeglut3-dev libglu1-mesa-dev libxmu-dev libxi-dev \ - libglfw3-dev libfreetype-dev libarmadillo-dev libhdf5-dev + libglfw3-dev libfreetype-dev libhdf5-dev # Install a very up to date compiler sudo apt install clang-23 clang-tools-23 # You can't apt install clang-23, as it's currently pre-release From 59c256b8582542df81e7dbf8dd5e2364208a7463 Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 12 Mar 2026 21:59:47 +0000 Subject: [PATCH 061/106] More readme --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c2df36d7..38962a4b 100644 --- a/README.md +++ b/README.md @@ -34,9 +34,8 @@ This quick start shows dependency installation for Linux, because on this platfo ```bash # Install dependencies for building graph1.cpp and (almost) all the other examples (assuming Debian-like OS) sudo apt install build-essential cmake git ninja-build \ - nlohmann-json3-dev librapidxml-dev \ - freeglut3-dev libglu1-mesa-dev libxmu-dev libxi-dev \ - libglfw3-dev libfreetype-dev libhdf5-dev + librapidxml-dev freeglut3-dev libglu1-mesa-dev libxmu-dev \ + libxi-dev libglfw3-dev libfreetype-dev libhdf5-dev # Install a very up to date compiler sudo apt install clang-23 clang-tools-23 # You can't apt install clang-23, as it's currently pre-release From df533372294c677e9baba50876ebada07e4faec7 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 13 Mar 2026 08:58:54 +0000 Subject: [PATCH 062/106] Latest maths --- maths | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths b/maths index 36ca9230..5cd66b06 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit 36ca92307b5e8040ec82ac7d8ae5a93842dcd42e +Subproject commit 5cd66b06c10b73897681c12efc0b21a643786c4b From 5a711bfb57a26a2941b5964cbf223be42d31a6d3 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 13 Mar 2026 10:09:13 +0000 Subject: [PATCH 063/106] Adds a place for bug reproduction --- CMakeLists.txt | 6 ++++++ bugrep/B.cppm | 9 +++++++++ bugrep/CMakeLists.txt | 7 +++++++ bugrep/a.cpp | 7 +++++++ 4 files changed, 29 insertions(+) create mode 100644 bugrep/B.cppm create mode 100644 bugrep/CMakeLists.txt create mode 100644 bugrep/a.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ad2c48a..b9355505 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,6 +188,12 @@ if(BUILD_TESTS) add_subdirectory(tests) endif(BUILD_TESTS) +option(BUILD_BUGREP "Build bugrep" OFF) +if(BUILD_BUGREP) + # bug reproduction + add_subdirectory(bugrep) +endif(BUILD_BUGREP) + # incbin for Visual Studio; code-generation for colour tables option(BUILD_UTILS "Build developer utils" OFF) if(BUILD_UTILS) diff --git a/bugrep/B.cppm b/bugrep/B.cppm new file mode 100644 index 00000000..2e782ee1 --- /dev/null +++ b/bugrep/B.cppm @@ -0,0 +1,9 @@ +export module B; + +export template +struct B +{ + B() {} + int f() { return tp; } + virtual void vf ([[maybe_unused]] int b) {} +}; diff --git a/bugrep/CMakeLists.txt b/bugrep/CMakeLists.txt new file mode 100644 index 00000000..5f4a2b63 --- /dev/null +++ b/bugrep/CMakeLists.txt @@ -0,0 +1,7 @@ +include_directories(BEFORE ${PROJECT_SOURCE_DIR}) + +add_executable(a a.cpp) +target_sources(a PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES + ${PROJECT_SOURCE_DIR}/bugrep/B.cppm +) diff --git a/bugrep/a.cpp b/bugrep/a.cpp new file mode 100644 index 00000000..606a6c3e --- /dev/null +++ b/bugrep/a.cpp @@ -0,0 +1,7 @@ +import B; + +int main() +{ + B<1> b; + return b.f(); +} From 8cf53ca27ee7f7f96c9b20a765664ef911e8bb5f Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 13 Mar 2026 10:28:05 +0000 Subject: [PATCH 064/106] Adds filenames --- bugrep/B.cppm | 1 + bugrep/a.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/bugrep/B.cppm b/bugrep/B.cppm index 2e782ee1..990fa3e5 100644 --- a/bugrep/B.cppm +++ b/bugrep/B.cppm @@ -1,3 +1,4 @@ +// B.cppm export module B; export template diff --git a/bugrep/a.cpp b/bugrep/a.cpp index 606a6c3e..443463ea 100644 --- a/bugrep/a.cpp +++ b/bugrep/a.cpp @@ -1,3 +1,4 @@ +// a.cpp import B; int main() From c898a91bb5d5943a2468abcd87dbb2e660b573f0 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 13 Mar 2026 11:01:41 +0000 Subject: [PATCH 065/106] Back to tuple, see if g++16 fixed that --- mplot/VisualOwnable.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index 2e937f0a..eb650f87 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -22,9 +22,9 @@ module; #include #include // clang was happy with a tuple: -//#include +#include // g++ generated an error with the tuple, so could use a pair: -#include +//#include #include #include #include @@ -1733,8 +1733,8 @@ export namespace mplot if (fout.is_open()) { fout << "{\n"; } } - //std::multimap, mplot::VisualModel*> > possible_centres; // tuple - std::multimap, mplot::VisualModel*> > possible_centres; // pair + std::multimap, mplot::VisualModel*> > possible_centres; // tuple + //std::multimap, mplot::VisualModel*> > possible_centres; // pair auto vmi = this->vm.begin(); while (vmi != this->vm.end()) { @@ -1761,8 +1761,8 @@ export namespace mplot if (tr_bb_centre[2] < 0.0f) { // Only if in front of viewer (z must be negative) // Perp. distance as key, value is tuple of BB centre and visualmodel pointer - //possible_centres.insert ({ pdist, { tr_bb_centre, (*vmi).get() } }); // tuple - possible_centres.insert ({ pdist, std::make_pair (tr_bb_centre, (*vmi).get()) }); // pair + possible_centres.insert ({ pdist, { tr_bb_centre, (*vmi).get() } }); // tuple + //possible_centres.insert ({ pdist, std::make_pair (tr_bb_centre, (*vmi).get()) }); // pair } } ++vmi; @@ -1774,13 +1774,13 @@ export namespace mplot } if (!possible_centres.empty()) { - //const auto [rcentre, vmptr] = possible_centres.begin()->second; // tuple - std::pair, mplot::VisualModel*> pr = possible_centres.begin()->second; // pair - // this->rotation_centre = rcentre; // tuple - this->rotation_centre = pr.first; // pair + const auto [rcentre, vmptr] = possible_centres.begin()->second; // tuple + //std::pair, mplot::VisualModel*> pr = possible_centres.begin()->second; // pair + this->rotation_centre = rcentre; // tuple + //this->rotation_centre = pr.first; // pair this->d_to_rotation_centre = this->rotation_centre.length(); - //if (options.test (visual_options::highlightRotationVM)) { vmptr->show_bb (true); } // tuple - if (options.test (visual_options::highlightRotationVM)) { pr.second->show_bb (true); } // pair + if (options.test (visual_options::highlightRotationVM)) { vmptr->show_bb (true); } // tuple + //if (options.test (visual_options::highlightRotationVM)) { pr.second->show_bb (true); } // pair } // else don't change rotation_centre } From c38c76f5e556a6de1f0fae4f7729673955900a0b Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 13 Mar 2026 11:05:15 +0000 Subject: [PATCH 066/106] Reverts last commit, g++16 still doesn't like that code. Will come back to a bugreport on it later --- mplot/VisualOwnable.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index eb650f87..2e937f0a 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -22,9 +22,9 @@ module; #include #include // clang was happy with a tuple: -#include +//#include // g++ generated an error with the tuple, so could use a pair: -//#include +#include #include #include #include @@ -1733,8 +1733,8 @@ export namespace mplot if (fout.is_open()) { fout << "{\n"; } } - std::multimap, mplot::VisualModel*> > possible_centres; // tuple - //std::multimap, mplot::VisualModel*> > possible_centres; // pair + //std::multimap, mplot::VisualModel*> > possible_centres; // tuple + std::multimap, mplot::VisualModel*> > possible_centres; // pair auto vmi = this->vm.begin(); while (vmi != this->vm.end()) { @@ -1761,8 +1761,8 @@ export namespace mplot if (tr_bb_centre[2] < 0.0f) { // Only if in front of viewer (z must be negative) // Perp. distance as key, value is tuple of BB centre and visualmodel pointer - possible_centres.insert ({ pdist, { tr_bb_centre, (*vmi).get() } }); // tuple - //possible_centres.insert ({ pdist, std::make_pair (tr_bb_centre, (*vmi).get()) }); // pair + //possible_centres.insert ({ pdist, { tr_bb_centre, (*vmi).get() } }); // tuple + possible_centres.insert ({ pdist, std::make_pair (tr_bb_centre, (*vmi).get()) }); // pair } } ++vmi; @@ -1774,13 +1774,13 @@ export namespace mplot } if (!possible_centres.empty()) { - const auto [rcentre, vmptr] = possible_centres.begin()->second; // tuple - //std::pair, mplot::VisualModel*> pr = possible_centres.begin()->second; // pair - this->rotation_centre = rcentre; // tuple - //this->rotation_centre = pr.first; // pair + //const auto [rcentre, vmptr] = possible_centres.begin()->second; // tuple + std::pair, mplot::VisualModel*> pr = possible_centres.begin()->second; // pair + // this->rotation_centre = rcentre; // tuple + this->rotation_centre = pr.first; // pair this->d_to_rotation_centre = this->rotation_centre.length(); - if (options.test (visual_options::highlightRotationVM)) { vmptr->show_bb (true); } // tuple - //if (options.test (visual_options::highlightRotationVM)) { pr.second->show_bb (true); } // pair + //if (options.test (visual_options::highlightRotationVM)) { vmptr->show_bb (true); } // tuple + if (options.test (visual_options::highlightRotationVM)) { pr.second->show_bb (true); } // pair } // else don't change rotation_centre } From 894c0fdfcd120f97fcd9aff846932529cf5704b2 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 13 Mar 2026 11:55:25 +0000 Subject: [PATCH 067/106] correct typed constants --- mplot/VisualOwnable.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index 2e937f0a..9b3ca534 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -1622,34 +1622,34 @@ export namespace mplot if (this->state.test (visual_state::sceneLocked) == false && _key == key::o && (mods & keymod::control) && action == keyaction::press) { - this->fov -= 2; - if (this->fov < 1.0) { this->fov = 2.0; } + this->fov -= 2.0f; + if (this->fov < 1.0f) { this->fov = 2.0f; } std::cout << "FOV reduced to " << this->fov << std::endl; } if (this->state.test (visual_state::sceneLocked) == false && _key == key::p && (mods & keymod::control) && action == keyaction::press) { - this->fov += 2; - if (this->fov > 179.0) { this->fov = 178.0; } + this->fov += 2.0f; + if (this->fov > 179.0f) { this->fov = 178.0f; } std::cout << "FOV increased to " << this->fov << std::endl; } if (this->state.test (visual_state::sceneLocked) == false && _key == key::u && (mods & keymod::control) && action == keyaction::press) { - this->zNear /= 2; + this->zNear /= 2.0f; std::cout << "zNear reduced to " << this->zNear << std::endl; } if (this->state.test (visual_state::sceneLocked) == false && _key == key::i && (mods & keymod::control) && action == keyaction::press) { - this->zNear *= 2; + this->zNear *= 2.0f; std::cout << "zNear increased to " << this->zNear << std::endl; } if (this->state.test (visual_state::sceneLocked) == false && _key == key::left_bracket && (mods & keymod::control) && action == keyaction::press) { - this->zFar /= 2; + this->zFar /= 2.0f; std::cout << "zFar reduced to " << this->zFar << std::endl; } if (this->state.test (visual_state::sceneLocked) == false && _key == key::right_bracket && (mods & keymod::control) && action == keyaction::press) { - this->zFar *= 2; + this->zFar *= 2.0f; std::cout << "zFar increased to " << this->zFar << std::endl; } From d09461517f84037e1bf8210cbacdc829256b4ded Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 13 Mar 2026 12:07:38 +0000 Subject: [PATCH 068/106] You don't need the constructor to demo the error --- bugrep/B.cppm | 1 - 1 file changed, 1 deletion(-) diff --git a/bugrep/B.cppm b/bugrep/B.cppm index 990fa3e5..53286c09 100644 --- a/bugrep/B.cppm +++ b/bugrep/B.cppm @@ -4,7 +4,6 @@ export module B; export template struct B { - B() {} int f() { return tp; } virtual void vf ([[maybe_unused]] int b) {} }; From 4c5b2b805aa5974503f9aaadfe9f727f7b7eaa58 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 13 Mar 2026 15:38:44 +0000 Subject: [PATCH 069/106] Adds ability to return to the previous viewing position after going into 'follow a VM' mode --- mplot/VisualOwnable.h | 159 ++++++++++++++++++++++++++++++++---------- 1 file changed, 123 insertions(+), 36 deletions(-) diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.h index 9b3ca534..f4f15663 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -86,12 +86,15 @@ export namespace mplot scrolling, //! True means that at least one of our VisualModels is an instanced rendering model haveInstanced, - //! When true, the instanced data SSBO needs to be copied to the GPU - //instancedNeedsUpdate, (gone to VisualResources) //! Left mouse button is down mouseButtonLeftPressed, //! Right mouse button is down - mouseButtonRightPressed + mouseButtonRightPressed, + //! If client code changes viewfollowsVMTranslations or viewFollowsVMBehind, this should be + //! set to signal to computeSceneview that the lastSceneview should be saved or restored to. + viewFollowsModeChanged, + //! Set true while the sceneview is 'zooming back' to the overview mode (or the whereever-you-left-it mode) + viewTransition }; //! Boolean options - similar to state, but more likely to be modified by client code @@ -768,10 +771,6 @@ export namespace mplot //! True if one of our added VisualModels is an instanced model bool haveInstanced() const { return this->state.test (visual_state::haveInstanced); } - //! Does our instanced data need to be pushed over to the GPU during render()? Now stored in VisualResources - //bool instancedNeedsUpdate() const { return this->state.test (visual_state::instancedNeedsUpdate); } - //void instancedNeedsUpdate (const bool val) { this->state.set (visual_state::instancedNeedsUpdate, val); } - /* * User-settable projection values for the near clipping distance, the far clipping distance * and the field of view of the camera. @@ -1159,6 +1158,25 @@ export namespace mplot return newpos; // rather than prop, as in get_cam_movement } + void switch_view_follows_mode() + { + // Relevant only if there is a followedVM + if (this->followedVM == nullptr) { return; } + + if (this->options.test (visual_options::viewFollowsVMBehind) == true + && this->options.test (visual_options::viewFollowsVMTranslations) == false) { + this->options.reset (visual_options::viewFollowsVMBehind); + this->options.set (visual_options::viewFollowsVMTranslations); + this->state.set (visual_state::viewFollowsModeChanged); + std::cout << "sceneview follows agent movements (overview)\n"; + } else { // this->options.test (mplot::visual_options::viewFollowsVMTranslations) == true + this->options.set (visual_options::viewFollowsVMBehind); + this->state.set (visual_state::viewFollowsModeChanged); + this->options.reset (visual_options::viewFollowsVMTranslations); + std::cout << "sceneview follows behind agent (follower view)\n"; + } + } + // Compile-time function to create a rotate-about-y transform static constexpr sm::mat rotate_about_y() { @@ -1172,19 +1190,10 @@ export namespace mplot sm::vec folcam_offset_tr = folcam_offset_tr_default; sm::quaternion folcam_offset_rot; - sm::mat update_folcam_viewmatrix() + sm::mat update_viewmatrix_towards_target (const sm::mat& target) { sm::mat fol_cur; - if (this->followedVM == nullptr) { return fol_cur; } - - // Target view from the followedVM - //sm::mat fol_targ = this->followedVM->getViewMatrix() * this->folcam_offset; - sm::mat rmat; - rmat.rotate (folcam_offset_rot); - sm::mat fol_targ = this->followedVM->getViewMatrix() * rmat; - fol_targ.translate (folcam_offset_tr); - // Compute folcam_viewmatrix from sceneview (it's the inverse, along with a rotation) constexpr sm::mat rotn_y = rotate_about_y(); sm::mat folcam_viewmatrix = this->sceneview.inverse() * rotn_y; @@ -1199,11 +1208,9 @@ export namespace mplot r_cur0.renormalize(); // get_cam_movement computes the positional shift - sm::vec pos_shift = this->get_cam_movement (fol_cur, fol_targ, - this->followedVM_vel, this->trans_tc); + sm::vec pos_shift = this->get_cam_movement (fol_cur, target, this->followedVM_vel, this->trans_tc); // get_cam_rotation computes the rotation for the next camera position - sm::quaternion cam_rotn = this->get_cam_rotation (r_cur0, fol_targ, - this->followedVM_rvel, this->rotn_tc); + sm::quaternion cam_rotn = this->get_cam_rotation (r_cur0, target, this->followedVM_rvel, this->rotn_tc); // set the translation/rotation into fol_cur fol_cur.pretranslate (pos_shift); @@ -1216,6 +1223,29 @@ export namespace mplot return fol_cur; } + // To zoom down to, and follow behind the agent + sm::mat update_folcam_viewmatrix() + { + if (this->followedVM == nullptr) { return sm::mat::identity(); } + // Target view from the followedVM + sm::mat rmat; + rmat.rotate (folcam_offset_rot); + sm::mat fol_targ = this->followedVM->getViewMatrix() * rmat; + fol_targ.translate (folcam_offset_tr); + // FIXME: I may want to update the lastSceneview matrix as fol_targ moves. + return update_viewmatrix_towards_target (fol_targ); + } + + // To zoom back to the drone view + sm::mat update_overcam_viewmatrix() + { + if (this->followedVM == nullptr) { return sm::mat::identity(); } + // fol_targ will be the inverse of the lastSceneview + constexpr sm::mat rotn_y = rotate_about_y(); + sm::mat targ = this->lastSceneview.inverse() * rotn_y; + return update_viewmatrix_towards_target (targ); + } + // A follow-me camera view void computeSceneview_for_follower() { @@ -1225,10 +1255,30 @@ export namespace mplot this->savedSceneview = this->sceneview; } + // When we're not close to the 'overview cam' location (which is the last place you were + // before you went into viewFollowsVMBehind mode) then we need this function to get there + void computeSceneview_for_overcam() + { + sm::mat overcam_viewmatrix = this->update_overcam_viewmatrix(); // target is lastSceneview + constexpr sm::mat rotn_y = rotate_about_y(); + this->sceneview = rotn_y * overcam_viewmatrix.inverse(); + this->savedSceneview = this->sceneview; + } + // This is called every time render() is called void computeSceneview() { if (this->options.test (visual_options::viewFollowsVMBehind) && this->followedVM != nullptr) { + + if (this->state.test (visual_state::viewFollowsModeChanged)) { + // Record sceneview now + this->lastSceneview = this->sceneview; + this->lastSceneview_tr = this->sceneview_tr; + // THEN, we can update lastSceneview whilst also updating agent location + // then zoom back to lastSceneview as the target. + this->state.reset (visual_state::viewFollowsModeChanged); + } + // Use scenetrans_delta to shift the view with the scrollwheel this->folcam_offset_tr += this->scenetrans_delta; this->scenetrans_delta.zero(); @@ -1237,23 +1287,55 @@ export namespace mplot return; } - if (std::abs(this->scenetrans_delta.sum()) > 0.0f || this->rotation_delta.is_zero_rotation() == false) { - // Calculate model view transformation - transforming from "model space" to "worldspace". - //std::cout << "standard view, call computeSceneview_about_rotation_centre\n"; - this->computeSceneview_about_rotation_centre(); - } // else don't change sceneview - //else { std::cout << "No changing sceneview...\n"; } - - //std::cout << "sceneview\n" << sceneview << std::endl; + if (this->state.test (visual_state::viewFollowsModeChanged)) { + // Changed back to normal, non-follower mode. Zoom back, so set viewTransition + std::cout << "viewFollowsModeChanged back to \"non-follow\"\n"; + this->state.set (visual_state::viewTransition); + this->state.reset (visual_state::viewFollowsModeChanged); + } + + // if sceneview is not close to lastSceneview and we have no commanded rotations + // (scenetrans_delta and rotation_delta are 0) then we make changes to return to + // lastSceneview: + if (this->followedVM != nullptr + && std::abs(this->scenetrans_delta.sum()) == 0.0f + && this->rotation_delta.is_zero_rotation() == true + && this->state.test (visual_state::viewTransition)) { + // zoom towards lastSceneview: + this->computeSceneview_for_overcam(); + // Update d_to_rotation_centre with distance to followedVM + // scene view in world frame + constexpr sm::mat rotn_y = rotate_about_y(); + sm::mat sv_viewmatrix = this->sceneview.inverse() * rotn_y; + // followed vm + sm::mat fvm = this->followedVM->getViewMatrix(); + + this->d_to_rotation_centre = (fvm.translation() - sv_viewmatrix.translation()).length(); + + // Did we get there? If so, set viewTransition false + if ((this->sceneview.translation() - this->lastSceneview.translation()).length() < 0.001f) { + this->state.reset (visual_state::viewTransition); + } + } else { - if (this->state.test (visual_state::scrolling)) { - this->scenetrans_delta.zero(); - this->state.reset (visual_state::scrolling); + if (std::abs(this->scenetrans_delta.sum()) > 0.0f || this->rotation_delta.is_zero_rotation() == false) { + // Calculate model view transformation - transforming from "model space" to "worldspace". + //std::cout << "standard view, call computeSceneview_about_rotation_centre\n"; + this->computeSceneview_about_rotation_centre(); + // As we had a commanded movement, cancel the viewTransition + this->state.reset (visual_state::viewTransition); + } // else don't change sceneview + //else { std::cout << "No changing sceneview...\n"; } + + if (this->state.test (visual_state::scrolling)) { + this->scenetrans_delta.zero(); + this->state.reset (visual_state::scrolling); + } } if (this->options.test (visual_options::viewFollowsVMTranslations) && this->followedVM != nullptr - && this->followedLastViewMatrix != this->followedVM->getViewMatrix()) { // NEED KNOWLEDGE OF VISUALMODEL + && this->followedLastViewMatrix != this->followedVM->getViewMatrix()) { // Move camera the difference between followedLastViewMatrix and // followedVM->getViewMatrix() in the screen frame of reference. @@ -1264,8 +1346,10 @@ export namespace mplot this->sceneview_tr.pretranslate (fol_screenframe); this->savedSceneview.pretranslate (fol_screenframe); this->savedSceneview_tr.pretranslate (fol_screenframe); + this->lastSceneview.pretranslate (fol_screenframe); + this->lastSceneview_tr.pretranslate (fol_screenframe); - this->followedLastViewMatrix = this->followedVM->getViewMatrix(); // NEED KNOWLEDGE OF VISUALMODEL + this->followedLastViewMatrix = this->followedVM->getViewMatrix(); } } @@ -1383,16 +1467,19 @@ export namespace mplot //! The sceneview matrix, which changes as the user moves the view with mouse //! movements. Initialized in VisualOwnable constructor. sm::mat sceneview; - //! The non-rotating sceneview matrix, updated only from mouse translations (avoiding rotations) sm::mat sceneview_tr; //! Saved sceneview at mouse button down sm::mat savedSceneview; - //! Saved sceneview_tr sm::mat savedSceneview_tr; + //! The sceneview when the user switched to a follow-me mode. This can become a target to return to when switching back. + sm::mat lastSceneview; + //! translation only version of lastSceneview + sm::mat lastSceneview_tr; + public: //! Getter for d_to_rotation_centre From 5cacb85dccf2a58b8befc45dd2b6d9f26802f60d Mon Sep 17 00:00:00 2001 From: Seb James Date: Sat, 14 Mar 2026 09:51:49 +0000 Subject: [PATCH 070/106] Adds compilers that work --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 38962a4b..01485eed 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,18 @@ Mathplot can be **integrated with GUI frameworks** including [Qt](https://doc.qt ## Quick Start +### Compilers that compile all the examples + +* clang-20 +* clang-21 +* clang-22 +* clang-23 (prerelease) + +Compilers that nearly work + +* clang-19 (ellipsoid example produces linker error) +* gcc-16 (prerelease) + This quick start shows dependency installation for Linux, because on this platform, it's a single call to apt (or your favourite package manager). If you're using a Mac, see [README.build.mac](https://github.com/sebsjames/mathplot/tree/main/README.build.mac.md) for help getting dependencies in place. It's [README.build.windows](https://github.com/sebsjames/mathplot/tree/main/README.build.windows.md) for Windows users. For notes on supported compilers, see [README.build.compiler](https://github.com/sebsjames/mathplot/tree/main/README.build.compiler.md) ```bash From ca673d7896bb2fd85fc6138596902c17688e28e4 Mon Sep 17 00:00:00 2001 From: Seb James Date: Sun, 15 Mar 2026 22:46:33 +0000 Subject: [PATCH 071/106] Basic examples now build with import std; --- CMakeLists.txt | 148 ++++++++++++++++++++++++++++++++++++---- examples/CMakeLists.txt | 3 + maths | 2 +- mplot/ColourMap.h | 9 +-- mplot/CoordArrows.h | 6 +- mplot/DatasetStyle.h | 6 +- mplot/GraphVisual.h | 3 +- mplot/ReadCurves.h | 5 +- mplot/Visual.h | 5 +- mplot/VisualCommon.h | 14 +--- mplot/VisualDataModel.h | 10 +-- mplot/VisualFace.h | 6 +- mplot/VisualModel.h | 86 ++++++++++------------- mplot/graphing.h | 16 +---- mplot/loadpng.h | 8 +-- 15 files changed, 194 insertions(+), 133 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9355505..8404ac22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,7 @@ -cmake_minimum_required(VERSION 3.28.5) +cmake_minimum_required(VERSION 3.30) + +set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444") + project(mathplot LANGUAGES CXX C) # Note that the project version is encoded in mplot/version.h and not in this CMakeLists.txt @@ -8,9 +11,12 @@ message(STATUS " (This can be changed with `cmake -DCMAKE_INSTALL_PREFIX=/some/ # # We're firmly at C++20. # -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_EXTENSIONS ON) +# Tell CMake that we explicitly want `import std`. This will initialize the +# property on all targets declared after this to 1 +set(CMAKE_CXX_MODULE_STD 1) include(CheckIncludeFileCXX) # CHECK_INCLUDE_FILE_CXX will be used in later scripts @@ -25,7 +31,7 @@ endif() # Add the host definition to CXXFLAGS along with other switches if (APPLE) - set(CMAKE_CXX_FLAGS "-Wall -g -O3") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -g -O3") else() if(CMAKE_CXX_COMPILER_ID MATCHES MSVC OR CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES MSVC) # Set flags for Windows. @@ -34,25 +40,20 @@ else() # /Zc:__cplusplus ensures __cplusplus define does not lie # /constexpr:steps is equivalent to -fconstexpr-steps or -fconstexpr-ops-limit if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) - set(CMAKE_CXX_FLAGS "-DNOMINMAX /EHsc /Zc:__cplusplus /constexpr:steps500000000") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNOMINMAX /EHsc /Zc:__cplusplus /constexpr:steps500000000") else() - set(CMAKE_CXX_FLAGS "-DNOMINMAX /EHsc /Zc:__cplusplus /clang:-fconstexpr-steps=500000000") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNOMINMAX /EHsc /Zc:__cplusplus /clang:-fconstexpr-steps=500000000") endif() elseif(CMAKE_CXX_COMPILER_ID MATCHES Intel) # To use Intel compiler, you can call cmake as: `cmake -DCMAKE_CXX_COMPILER=icpc ..` or `CXX=icpc cmake ..` message(WARNING "Intel compiler has not been tested for some time") - set(CMAKE_CXX_FLAGS "-Wall -g -std=c++20 -xHOST -O3") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -g -std=c++20 -xHOST -O3") else() # GCC or Clang if(CMAKE_CXX_COMPILER_ID MATCHES GNU) - # Add compiler version check, to ensure gcc is version 14? 15? or later. - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14) - message(FATAL_ERROR "GCC version must be at least 14") - else() - message(STATUS "GCC version ${CMAKE_CXX_COMPILER_VERSION} OK!") - endif() + message(WARNING "GCC probably won't work, try clang-20") endif() set(COMPREHENSIVE_WARNING_FLAGS "-Wall -Wextra -Wpedantic -pedantic-errors -Werror -Wfatal-errors -Wno-psabi") - set(CMAKE_CXX_FLAGS "-g ${COMPREHENSIVE_WARNING_FLAGS} -O3") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g ${COMPREHENSIVE_WARNING_FLAGS} -O3") if(CMAKE_CXX_COMPILER_ID MATCHES GNU) # Make it possible to compile complex constexpr functions (gcc only) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fconstexpr-ops-limit=5000000000") @@ -178,6 +179,125 @@ if (NOT HAVE_RAPIDXML) include_directories("${PROJECT_SOURCE_DIR}/include/rapidxml-1.13") endif() # else we have it in a directory included by default in the path +# +# sebsjames/maths module groups +# +set(SM_CONSTEXPR_MATH_MODULES + ${PROJECT_SOURCE_DIR}/sm/mathconst + ${PROJECT_SOURCE_DIR}/sm/constexpr_math +) +set(SM_POLYSOLVE_MODULES + ${SM_CONSTEXPR_MATH_MODULES} + ${PROJECT_SOURCE_DIR}/sm/polysolve +) +set(SM_BESSEL_I0_MODULES + ${SM_POLYSOLVE_MODULES} + ${PROJECT_SOURCE_DIR}/sm/bessel_i0 +) +set(SM_RANDOM_MODULES + ${SM_BESSEL_I0_MODULES} + ${PROJECT_SOURCE_DIR}/sm/random +) +set(SM_RANGE_MODULES + ${SM_CONSTEXPR_MATH_MODULES} + ${PROJECT_SOURCE_DIR}/sm/trait_tests + ${PROJECT_SOURCE_DIR}/sm/range +) +set(SM_VEC_MODULES + ${SM_RANGE_MODULES} + ${SM_RANDOM_MODULES} + ${PROJECT_SOURCE_DIR}/sm/vec +) +set(SM_VVEC_MODULES + ${SM_RANGE_MODULES} + ${SM_RANDOM_MODULES} + ${PROJECT_SOURCE_DIR}/sm/vvec +) +set(SM_SCALE_MODULES + ${SM_VVEC_MODULES} + ${PROJECT_SOURCE_DIR}/sm/scale +) +set(SM_UTIL_MODULES + ${PROJECT_SOURCE_DIR}/sm/trait_tests + ${PROJECT_SOURCE_DIR}/sm/util +) +set(SM_HDFDATA_MODULES + ${SM_VEC_MODULES} + ${SM_VVEC_MODULES} + ${SM_UTIL_MODULES} + ${PROJECT_SOURCE_DIR}/sm/hdfdata +) +set(SM_QUATERNION_MODULES + ${SM_VEC_MODULES} + ${PROJECT_SOURCE_DIR}/sm/quaternion +) +set(SM_MAT_MODULES + ${SM_QUATERNION_MODULES} + ${PROJECT_SOURCE_DIR}/sm/mat +) +set(SM_BEZCOORD_MODULES + ${SM_VEC_MODULES} + ${PROJECT_SOURCE_DIR}/sm/bezcoord +) +set(SM_HEX_MODULES + ${SM_BEZCOORD_MODULES} + ${PROJECT_SOURCE_DIR}/sm/hex +) +set(SM_WINDER_MODULES + ${SM_VEC_MODULES} + ${PROJECT_SOURCE_DIR}/sm/winder +) +set(SM_BOOTSTRAP_MODULES + ${SM_VEC_MODULES} + ${SM_VVEC_MODULES} + ${PROJECT_SOURCE_DIR}/sm/bootstrap +) +set(SM_GRID_MODULES + ${SM_VEC_MODULES} + ${SM_VVEC_MODULES} + ${PROJECT_SOURCE_DIR}/sm/grid +) +set(SM_ALGO_MODULES + ${SM_VEC_MODULES} + ${PROJECT_SOURCE_DIR}/sm/algo +) +set(SM_NM_SIMPLEX_MODULES + ${SM_ALGO_MODULES} + ${SM_VVEC_MODULES} + ${PROJECT_SOURCE_DIR}/sm/nm_simplex +) +set(SM_HISTO_MODULES + ${SM_VEC_MODULES} + ${SM_VVEC_MODULES} + ${PROJECT_SOURCE_DIR}/sm/histo +) +set(SM_BOXFILTER_MODULES + ${SM_VEC_MODULES} + ${SM_VVEC_MODULES} + ${PROJECT_SOURCE_DIR}/sm/boxfilter +) +set(SM_GEOMETRY_MODULES + ${SM_ALGO_MODULES} + ${SM_VVEC_MODULES} + ${PROJECT_SOURCE_DIR}/sm/geometry +) +set(SM_BEZCURVE_MODULES + ${SM_BEZCOORD_MODULES} + ${SM_MAT_MODULES} + ${SM_NM_SIMPLEX_MODULES} + ${PROJECT_SOURCE_DIR}/sm/binomial + ${PROJECT_SOURCE_DIR}/sm/bezcurve +) +set(SM_BEZCURVEPATH_MODULES + ${SM_BEZCURVE_MODULES} + ${PROJECT_SOURCE_DIR}/sm/bezcurvepath +) +set(SM_HEXGRID_MODULES + ${SM_BEZCURVEPATH_MODULES} + ${SM_HEX_MODULES} + ${PROJECT_SOURCE_DIR}/sm/hexgrid +) + # All the mathplot headers are here add_subdirectory(mplot) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index d032ada7..54b552a4 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -5,10 +5,13 @@ set(SM_CORE_MODULES ${PROJECT_SOURCE_DIR}/maths/sm/mathconst ${PROJECT_SOURCE_DIR}/maths/sm/constexpr_math ${PROJECT_SOURCE_DIR}/maths/sm/range + ${PROJECT_SOURCE_DIR}/maths/sm/polysolve + ${PROJECT_SOURCE_DIR}/maths/sm/bessel_i0 ${PROJECT_SOURCE_DIR}/maths/sm/random ${PROJECT_SOURCE_DIR}/maths/sm/vec ${PROJECT_SOURCE_DIR}/maths/sm/quaternion ${PROJECT_SOURCE_DIR}/maths/sm/mat + ${PROJECT_SOURCE_DIR}/maths/sm/trait_tests ${PROJECT_SOURCE_DIR}/maths/sm/util ${PROJECT_SOURCE_DIR}/maths/sm/base64 ${PROJECT_SOURCE_DIR}/maths/sm/crc32 diff --git a/maths b/maths index 5cd66b06..6dfa56c8 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit 5cd66b06c10b73897681c12efc0b21a643786c4b +Subproject commit 6dfa56c84600495c579689fcef34b2261b2a310a diff --git a/mplot/ColourMap.h b/mplot/ColourMap.h index e3291009..19a00491 100644 --- a/mplot/ColourMap.h +++ b/mplot/ColourMap.h @@ -1,13 +1,14 @@ module; #include // William Lenthe's implementation of perceptually uniform colour maps -#include -#include -#include -#include +//#include +//#include +//#include +//#include export module mplot.colourmap; +import std; export import :colourmaps_cet; // Colour map tables from CET export import :colourmaps_crameri; // Colour map tables from Fabio Crameri export import :colourmap_lists; // Colour map tables from matplotlib diff --git a/mplot/CoordArrows.h b/mplot/CoordArrows.h index 019f48ca..ef3533ba 100644 --- a/mplot/CoordArrows.h +++ b/mplot/CoordArrows.h @@ -6,13 +6,9 @@ * \author Seb James * \date 2019 */ -module; - -#include -#include - export module mplot.coordarrows; +import std; import sm.vec; import mplot.gl.version; export import mplot.visualmodel; diff --git a/mplot/DatasetStyle.h b/mplot/DatasetStyle.h index 1013cfdf..c28de284 100644 --- a/mplot/DatasetStyle.h +++ b/mplot/DatasetStyle.h @@ -1,10 +1,6 @@ -module; - -#include -#include - export module mplot.datasetstyle; +import std; import sm.vec; import sm.flags; diff --git a/mplot/GraphVisual.h b/mplot/GraphVisual.h index 6fb1ace5..25705a4a 100644 --- a/mplot/GraphVisual.h +++ b/mplot/GraphVisual.h @@ -17,8 +17,6 @@ module; #include #include -#include - export module mplot.graphvisual; import mplot.graphing; @@ -33,6 +31,7 @@ export import sm.vvec; import sm.quaternion; import sm.histo; import sm.grid; +import sm.trait_tests; import mplot.tools; import mplot.colour; diff --git a/mplot/ReadCurves.h b/mplot/ReadCurves.h index f4b9fbdc..6f96c6d6 100644 --- a/mplot/ReadCurves.h +++ b/mplot/ReadCurves.h @@ -21,9 +21,10 @@ #include #include -#include #include -#include // for tools::searchReplace and tools::containsOnlyWhitespace +//#include // for tools::searchReplace and tools::containsOnlyWhitespace +import mplot.tools; +import sm.bezcurvepath; namespace mplot { diff --git a/mplot/Visual.h b/mplot/Visual.h index d6e31517..832eea28 100644 --- a/mplot/Visual.h +++ b/mplot/Visual.h @@ -22,12 +22,9 @@ module; # include #endif // _glfw3_h_ -#include -#include -#include - export module mplot.visual; +import std; export import mplot.gl.version; export import mplot.win_t; diff --git a/mplot/VisualCommon.h b/mplot/VisualCommon.h index 4d48931c..76b5ae32 100644 --- a/mplot/VisualCommon.h +++ b/mplot/VisualCommon.h @@ -3,17 +3,9 @@ * * Author: Seb James. */ -module; - -#include -#include -#include -#include -#include -#include - export module mplot.visualcommon; +import std; import sm.vec; import sm.range; import sm.vvec; @@ -24,7 +16,7 @@ import mplot.tools; export namespace mplot { // State/options flags for VisualModels - enum class vm_bools : uint32_t + enum class vm_bools : std::uint32_t { postVertexInitRequired, twodimensional, // If true, then this VisualModel should always be viewed in a plane - it's a 2D model @@ -40,7 +32,7 @@ export namespace mplot { std::string name; sm::mat transform; - sm::vvec indices; + sm::vvec indices; sm::vvec> positions; sm::vvec> normals; sm::vvec> colours; diff --git a/mplot/VisualDataModel.h b/mplot/VisualDataModel.h index 5e9a63b5..2b7c028d 100644 --- a/mplot/VisualDataModel.h +++ b/mplot/VisualDataModel.h @@ -1,13 +1,9 @@ /*! * VisualModels which have data. */ -module; - -#include -#include - export module mplot.visualdatamodel; +import std; import sm.vec; import sm.vvec; import sm.scale; @@ -78,7 +74,7 @@ export namespace mplot } //! An overridable function to set the colour of rect ri - std::array setColour (uint64_t ri) + std::array setColour (std::uint64_t ri) { std::array clr = { 0.0f, 0.0f, 0.0f }; if (this->cm.numDatums() == 3) { @@ -139,7 +135,7 @@ export namespace mplot }; //! VisualDataModel implementation that deals with std::vector pointers to scalar/vector data - template + template struct VisualDataModel_impl : public VisualDataModel_impl_base { void setScalarData (const std::vector* _data) { this->scalarData = _data; } diff --git a/mplot/VisualFace.h b/mplot/VisualFace.h index fe43db11..edfc7bdc 100644 --- a/mplot/VisualFace.h +++ b/mplot/VisualFace.h @@ -21,11 +21,6 @@ module; #include #include FT_FREETYPE_H -#include -#include -#include -#include - #include /* @@ -34,6 +29,7 @@ module; export module mplot.visualface; +import std; import mplot.visualcommon; import mplot.visualfont; import mplot.textfeatures; diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index 762743ac..40b28576 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -17,25 +17,9 @@ module; # include #endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - export module mplot.visualmodel; +import std; import sm.mathconst; import sm.geometry_polyhedra; import sm.quaternion; @@ -104,7 +88,7 @@ export namespace mplot //! Common code to call after the vertices have been set up. GL has to have been initialised. void postVertexInit() { - if (this->parentVis == std::numeric_limits::max()) { + if (this->parentVis == std::numeric_limits::max()) { throw std::runtime_error ("parentVis is unset"); } GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->parentVis); @@ -475,14 +459,14 @@ export namespace mplot h = (h << 5) - 1 + std::hash{}(this->vertexNormals[i]); } for (std::size_t i = 0u; i < this->indices.size(); ++i) { - h = (h << 5) - 1 + std::hash{}(this->indices[i]); + h = (h << 5) - 1 + std::hash{}(this->indices[i]); } return h; } // Get a single position from vertexPositions, using the index into the vector // interpretation of vertexPositions - sm::vec get_position (const uint32_t vec_idx) const + sm::vec get_position (const std::uint32_t vec_idx) const { auto vp = reinterpret_cast>*>(&this->vertexPositions); return (*vp)[vec_idx]; @@ -490,14 +474,14 @@ export namespace mplot // Get a single normal from vertexNormals, using the index into the vector // interpretation of vertexNormals - sm::vec get_normal (const uint32_t vec_idx) const + sm::vec get_normal (const std::uint32_t vec_idx) const { auto vn = reinterpret_cast>*>(&this->vertexNormals); return (*vn)[vec_idx]; } // Get the area of the triangle whose start index is vec_idx - float get_area (const uint32_t vec_idx0, const uint32_t vec_idx1, const uint32_t vec_idx2) const + float get_area (const std::uint32_t vec_idx0, const std::uint32_t vec_idx1, const std::uint32_t vec_idx2) const { auto vp = reinterpret_cast>*>(&this->vertexPositions); auto t0 = (*vp)[vec_idx0]; @@ -526,11 +510,11 @@ export namespace mplot // Treat vertexPositions as a vector of vec: auto vp = reinterpret_cast>*>(&this->vertexPositions); - uint32_t vps = vp->size(); - std::unordered_map, std::set, sm::vec::hash> equiv_v; - uint32_t i = 0; + std::uint32_t vps = vp->size(); + std::unordered_map, std::set, sm::vec::hash> equiv_v; + std::uint32_t i = 0; for (auto p : *vp) { equiv_v[p].insert (i++); } - std::map> equiv; + std::map> equiv; for (auto e : equiv_v) { equiv[*e.second.begin()] = e.second; } if constexpr (debug_mn) { for (auto e : equiv) { @@ -543,8 +527,8 @@ export namespace mplot // Make inverse of equiv to translate from original (indices, vertexPositions) index to // new topographic mesh index - sm::vvec navmesh_idx (vps, 0); - uint32_t vcount = 0; + sm::vvec navmesh_idx (vps, 0); + std::uint32_t vcount = 0; i = 0; for (auto eqs : equiv) { vcount += eqs.second.size(); @@ -568,7 +552,7 @@ export namespace mplot navmesh->vertex.resize (equiv.size(), mesh::vertex{}); i = 0; for (auto eq : equiv) { - navmesh->vertex[i++] = { (*vp)[eq.first], std::numeric_limits::max() }; + navmesh->vertex[i++] = { (*vp)[eq.first], std::numeric_limits::max() }; } // We're turing a triangle mesh into a navmesh. Don't know what to do if there are stray vertices. @@ -578,13 +562,13 @@ export namespace mplot // Lastly, generate edges. For which we require use of indices, which is expressed in // terms of the old indices. That lookup is navmesh_idx. - for (uint32_t i = 0; i < this->indices.size(); i += 3) { + for (std::uint32_t i = 0; i < this->indices.size(); i += 3) { // Add three halfedges for the triangle - const uint32_t hesz = navmesh->halfedge.size(); - const uint32_t he0 = hesz; - const uint32_t he1 = hesz + 1; - const uint32_t he2 = hesz + 2; + const std::uint32_t hesz = navmesh->halfedge.size(); + const std::uint32_t he0 = hesz; + const std::uint32_t he1 = hesz + 1; + const std::uint32_t he2 = hesz + 2; if constexpr (debug_mn) { std::cout << "setting halfedge["<< he0 << "] to { {" @@ -603,9 +587,9 @@ export namespace mplot navmesh->halfedge.resize (hesz + 3, {}); // Now, could also try to identify LINES - navmesh->halfedge[he0] = { {navmesh_idx[indices[i ]], navmesh_idx[indices[i + 1]]}, std::numeric_limits::max(), he1, he2, 0u }; - navmesh->halfedge[he1] = { {navmesh_idx[indices[i + 1]], navmesh_idx[indices[i + 2]]}, std::numeric_limits::max(), he2, he0, 0u }; - navmesh->halfedge[he2] = { {navmesh_idx[indices[i + 2]], navmesh_idx[indices[i ]]}, std::numeric_limits::max(), he0, he1, 0u }; + navmesh->halfedge[he0] = { {navmesh_idx[indices[i ]], navmesh_idx[indices[i + 1]]}, std::numeric_limits::max(), he1, he2, 0u }; + navmesh->halfedge[he1] = { {navmesh_idx[indices[i + 1]], navmesh_idx[indices[i + 2]]}, std::numeric_limits::max(), he2, he0, 0u }; + navmesh->halfedge[he2] = { {navmesh_idx[indices[i + 2]], navmesh_idx[indices[i ]]}, std::numeric_limits::max(), he0, he1, 0u }; if constexpr (debug_mn) { std::cout << "halfedge["<< hesz << "] contains: vi:" @@ -669,7 +653,7 @@ export namespace mplot this->navmesh = std::make_unique(); // Have we got a pre-computed navmesh file for the halfedge twin relationships? - uint64_t h = this->hash(); + std::uint64_t h = this->hash(); if (navmesh_dir.empty()) { navmesh_dir = mplot::tools::getTmpPath(); } else { @@ -734,7 +718,7 @@ export namespace mplot GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->parentVis); glfn->GetIntegerv (GL_CURRENT_PROGRAM, &prev_shader); // Ensure the correct program is in play for this VisualModel - uint32_t gprog = mplot::VisualResources::i().get_gprog (this->parentVis); + std::uint32_t gprog = mplot::VisualResources::i().get_gprog (this->parentVis); glfn->UseProgram (gprog); if (!this->indices.empty()) { @@ -1167,14 +1151,14 @@ export namespace mplot throw std::runtime_error ("set_instance_data: params vvecs should all have same size (colour, rotn, scale)"); } - for (size_t i = 0; i < position.size(); ++i) { + for (std::size_t i = 0; i < position.size(); ++i) { // Get access to the SSBO in VisualResources and add the 3 floats in position[i] at // the location defined by this->instance_start + i mplot::VisualResources::i().insert_instance_data (this->instance_start + i, position[i]); } this->instance_count = position.size(); - for (size_t i = 0; i < colour.size(); ++i) { + for (std::size_t i = 0; i < colour.size(); ++i) { mplot::VisualResources::i().insert_instparam_data (this->instance_start + i, colour[i], alpha[i], scale[i]); } this->instparam_count = colour.size(); @@ -1183,9 +1167,9 @@ export namespace mplot } //! Setter for the parent ID, parentVis - void set_parent (const uint32_t _vis) + void set_parent (const std::uint32_t _vis) { - if (this->parentVis == std::numeric_limits::max()) { this->parentVis = _vis; } + if (this->parentVis == std::numeric_limits::max()) { this->parentVis = _vis; } } // Flags defaults. @@ -1303,7 +1287,7 @@ export namespace mplot float alpha = 1.0f; // The mplot::VisualBase in which this model exists. - uint32_t parentVis = std::numeric_limits::max(); + std::uint32_t parentVis = std::numeric_limits::max(); //! A vector of pointers to text models that should be rendered. std::vector>> texts; @@ -1313,7 +1297,7 @@ export namespace mplot { std::size_t sz = dat.size() * sizeof(float); - if (this->parentVis == std::numeric_limits::max()) { + if (this->parentVis == std::numeric_limits::max()) { throw std::runtime_error ("parentVis is unset"); } GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->parentVis); @@ -1360,7 +1344,7 @@ export namespace mplot mg.validate(); bool single_colr = mg.colours.empty(); - for (uint32_t i = 0; i < mg.positions.size(); ++i) { + for (std::uint32_t i = 0; i < mg.positions.size(); ++i) { // We apply mg.transform *here*, rather than writing it into the viewmatrix. This is // because other elements of this visual model may be added with the assumption of an // identity viewmatrix. @@ -1372,7 +1356,7 @@ export namespace mplot this->vertex_push (mg.colours[i], this->vertexColors); } } - for (uint32_t i = 0; i < mg.indices.size(); ++i) { + for (std::uint32_t i = 0; i < mg.indices.size(); ++i) { this->indices.push_back (mg.indices[i] + this->idx); } this->idx += mg.positions.size(); @@ -1922,7 +1906,7 @@ export namespace mplot v.renormalize(); // Push corner vertices - size_t vpsz = this->vertexPositions.size(); + std::size_t vpsz = this->vertexPositions.size(); this->vertexPositions.resize (vpsz + 12); for (unsigned int i = 0; i < 3u; ++i) { this->vertexPositions[vpsz++] = c1[i]; } for (unsigned int i = 0; i < 3u; ++i) { this->vertexPositions[vpsz++] = c2[i]; } @@ -1930,8 +1914,8 @@ export namespace mplot for (unsigned int i = 0; i < 3u; ++i) { this->vertexPositions[vpsz++] = c4[i]; } // Colours/normals - size_t vcsz = this->vertexColors.size(); - size_t vnsz = this->vertexNormals.size(); + std::size_t vcsz = this->vertexColors.size(); + std::size_t vnsz = this->vertexNormals.size(); this->vertexColors.resize (vcsz + 12); this->vertexNormals.resize (vnsz + 12); for (unsigned int i = 0; i < 4u; ++i) { @@ -1941,7 +1925,7 @@ export namespace mplot } } - size_t i0 = this->indices.size(); + std::size_t i0 = this->indices.size(); this->indices.resize (i0 + 6, 0); this->indices[i0++] = this->idx; this->indices[i0++] = this->idx + 2; diff --git a/mplot/graphing.h b/mplot/graphing.h index b27a871f..c349cad3 100644 --- a/mplot/graphing.h +++ b/mplot/graphing.h @@ -5,23 +5,9 @@ * Seb James * March 2025 */ -module; - -#include -#include -#include -#include -#include -#ifdef MPLOT_HAVE_STD_FORMAT -# include -#else -# include -# include -# include -#endif - export module mplot.graphing; +import std; import sm.constexpr_math; import sm.range; import sm.algo; diff --git a/mplot/loadpng.h b/mplot/loadpng.h index 11070266..4be3500b 100644 --- a/mplot/loadpng.h +++ b/mplot/loadpng.h @@ -6,15 +6,9 @@ module; #define LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS 1 #include -#include -#include -#include -#include -#include -#include - export module mplot.loadpng; +import std; export import sm.vec; import sm.vvec; From 6325e8a5c0e40d6176ec892cff112cc16b31eb4f Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 07:49:17 +0000 Subject: [PATCH 072/106] Notes on modules --- README.modules.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 README.modules.md diff --git a/README.modules.md b/README.modules.md new file mode 100644 index 00000000..6bd09241 --- /dev/null +++ b/README.modules.md @@ -0,0 +1,23 @@ +Modules build + +Building with full modules, including import std; + +The examples built were: + +breadcrumbs +cray_eye +ellipsoid +geodesic +graph1 +grid_simple +helloworld +hexgrid +rod +rod_with_normals +showcase +vectorvis + +Test machine: Rog laptop, 13th Gen Intel(R) Core(TM) i9-13980HX + +clang20: 42 sec, (13min user time) +clang21: Can't test yet, need libc++ built from clang21 From e6755a088e5bb0b526cecce9467472bbb960ae4b Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 07:58:47 +0000 Subject: [PATCH 073/106] More notes on buildtimes --- README.modules.md | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/README.modules.md b/README.modules.md index 6bd09241..ffcfee93 100644 --- a/README.modules.md +++ b/README.modules.md @@ -1,6 +1,4 @@ -Modules build - -Building with full modules, including import std; +# Modules build times The examples built were: @@ -19,5 +17,26 @@ vectorvis Test machine: Rog laptop, 13th Gen Intel(R) Core(TM) i9-13980HX -clang20: 42 sec, (13min user time) +## With `import std;` + +Building with *full* modules, including import std; + +clang20: 42-46 sec, (13min user time) + +breadcrumbs rebuild time after touch breadcrumbs.cpp (rebuilds 4 items): 5.8 s +breadcrumbs rebuild time after touch VisualModel (rebuilds 130 items): 24 s + clang21: Can't test yet, need libc++ built from clang21 + +## Without `import std;` + +clang20: 74 s + +breadcrumbs rebuild time after touch breadcrumbs.cpp: 5.93 s + +## Header only + +clang20: + +breadcrumbs rebuild time after touch breadcrumbs.cpp (rebuilds 4 items): s +breadcrumbs rebuild time after touch VisualModel (rebuilds 130 items): s From d5d238b03cd29dc8da4dcd15158eb88283025d13 Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 08:04:17 +0000 Subject: [PATCH 074/106] Notes on header only build time --- README.modules.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.modules.md b/README.modules.md index ffcfee93..26486256 100644 --- a/README.modules.md +++ b/README.modules.md @@ -36,7 +36,7 @@ breadcrumbs rebuild time after touch breadcrumbs.cpp: 5.93 s ## Header only -clang20: +clang20: 19 s -breadcrumbs rebuild time after touch breadcrumbs.cpp (rebuilds 4 items): s -breadcrumbs rebuild time after touch VisualModel (rebuilds 130 items): s +breadcrumbs rebuild time after touch breadcrumbs.cpp (rebuilds 4 items): 6.9 s +breadcrumbs rebuild time after touch VisualModel (rebuilds 130 items): 6.9 s From 19e39cb419f2c2a58fd4a7a1c44d7a5d5d3a8dbd Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 08:08:48 +0000 Subject: [PATCH 075/106] Last bit of info about build times with and without modules --- README.modules.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/README.modules.md b/README.modules.md index 26486256..2ccd3791 100644 --- a/README.modules.md +++ b/README.modules.md @@ -17,14 +17,20 @@ vectorvis Test machine: Rog laptop, 13th Gen Intel(R) Core(TM) i9-13980HX +All were built with this cmake line: + +```bash +CC=clang-20 CXX=clang++-20 cmake .. -G Ninja -DCMAKE_CXX_FLAGS=-stdlib=libc++ +``` + ## With `import std;` Building with *full* modules, including import std; clang20: 42-46 sec, (13min user time) -breadcrumbs rebuild time after touch breadcrumbs.cpp (rebuilds 4 items): 5.8 s -breadcrumbs rebuild time after touch VisualModel (rebuilds 130 items): 24 s +breadcrumbs rebuild time after touch breadcrumbs.cpp (rebuilds 4 items): 5.8 s +breadcrumbs rebuild time after touch VisualModel (rebuilds 130 items): 24.0 s clang21: Can't test yet, need libc++ built from clang21 @@ -32,11 +38,12 @@ clang21: Can't test yet, need libc++ built from clang21 clang20: 74 s -breadcrumbs rebuild time after touch breadcrumbs.cpp: 5.93 s +breadcrumbs rebuild time after touch breadcrumbs.cpp: 5.9 s +breadcrumbs rebuild time after touch VisualModel (rebuilds 11 items): 17.6 s ## Header only clang20: 19 s -breadcrumbs rebuild time after touch breadcrumbs.cpp (rebuilds 4 items): 6.9 s -breadcrumbs rebuild time after touch VisualModel (rebuilds 130 items): 6.9 s +breadcrumbs rebuild time after touch breadcrumbs.cpp (rebuilds 4 items): 6.9 s +breadcrumbs rebuild time after touch VisualModel (rebuilds 130 items): 6.9 s From 9386b4f7015358ce3e65fa600b90733557a83b98 Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 10:03:48 +0000 Subject: [PATCH 076/106] More results --- README.modules.md | 61 +++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/README.modules.md b/README.modules.md index 2ccd3791..66c3fc6a 100644 --- a/README.modules.md +++ b/README.modules.md @@ -1,49 +1,68 @@ # Modules build times +## Matplot examples + The examples built were: -breadcrumbs -cray_eye -ellipsoid -geodesic -graph1 -grid_simple -helloworld -hexgrid -rod -rod_with_normals -showcase -vectorvis +``` +breadcrumbs cray_eye ellipsoid geodesic graph1 grid_simple helloworld hexgrid rod rod_with_normals showcase vectorvis +``` Test machine: Rog laptop, 13th Gen Intel(R) Core(TM) i9-13980HX -All were built with this cmake line: +All were built with this cmake line - i.e using clang20 and libc++: ```bash CC=clang-20 CXX=clang++-20 cmake .. -G Ninja -DCMAKE_CXX_FLAGS=-stdlib=libc++ ``` -## With `import std;` +### With `import std;` Building with *full* modules, including import std; -clang20: 42-46 sec, (13min user time) +All examples from scratch: 42-46 sec, (13min user time) breadcrumbs rebuild time after touch breadcrumbs.cpp (rebuilds 4 items): 5.8 s breadcrumbs rebuild time after touch VisualModel (rebuilds 130 items): 24.0 s -clang21: Can't test yet, need libc++ built from clang21 +### Without `import std;` -## Without `import std;` - -clang20: 74 s +All examples from scratch: 74 s breadcrumbs rebuild time after touch breadcrumbs.cpp: 5.9 s breadcrumbs rebuild time after touch VisualModel (rebuilds 11 items): 17.6 s -## Header only +### Header only -clang20: 19 s +All examples from scratch: 19 s breadcrumbs rebuild time after touch breadcrumbs.cpp (rebuilds 4 items): 6.9 s breadcrumbs rebuild time after touch VisualModel (rebuilds 130 items): 6.9 s + +## Complex example + +Test machine: Scan desktop, Intel(R) Core(TM) Ultra 9 285K + +Building 'antpov'. Using clang20 across the tests with: + +```bash +CC=clang-20 CXX=clang++-20 cmake .. -G Ninja -DCMAKE_CXX_FLAGS=-stdlib=libc++ +``` + +### Without `import std;` + +Build antpov from scratch (138 items): 26.3 s + +Build after touch antpov.cpp: 8.9 s + +### With `import std;` + +Note that the final link does not complete at present, but I think these times are representative + +Build antpov from scratch (150 items): 19.5 s + +Build after touch antpov.cpp (4 items): 7.6 s + +## Header only + +With clang20... \ No newline at end of file From a8d04eed80ad1a34e0c4f0df08924134aa8f78a2 Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 10:07:09 +0000 Subject: [PATCH 077/106] Last results for header only antpov --- README.modules.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.modules.md b/README.modules.md index 66c3fc6a..be9c0318 100644 --- a/README.modules.md +++ b/README.modules.md @@ -46,7 +46,7 @@ Test machine: Scan desktop, Intel(R) Core(TM) Ultra 9 285K Building 'antpov'. Using clang20 across the tests with: ```bash -CC=clang-20 CXX=clang++-20 cmake .. -G Ninja -DCMAKE_CXX_FLAGS=-stdlib=libc++ +CC=clang-20 CXX=clang++-20 cmake .. -G Ninja -DOptiX_INSTALL_DIR=~/src/NVIDIA-OptiX-SDK-8.0.0-linux64-x86_64 -DCMAKE_CXX_FLAGS=-stdlib=libc++ ``` ### Without `import std;` @@ -65,4 +65,6 @@ Build after touch antpov.cpp (4 items): 7.6 s ## Header only -With clang20... \ No newline at end of file +Build antpov from scratch (2 items): 17.4 s + +Build after touch antpov.cpp (2 items): 17.4 s From 7d52b5b457573930dc1063f790ce4c81e2de6a4b Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 11:18:07 +0000 Subject: [PATCH 078/106] Un-import std; --- mplot/ColourMap.h | 9 ++++----- mplot/CoordArrows.h | 6 +++++- mplot/DatasetStyle.h | 6 +++++- mplot/ReadCurves.h | 2 +- mplot/Visual.h | 5 ++++- mplot/VisualCommon.h | 10 +++++++++- mplot/VisualDataModel.h | 6 +++++- mplot/VisualFace.h | 6 +++++- mplot/VisualModel.h | 18 +++++++++++++++++- mplot/graphing.h | 16 +++++++++++++++- mplot/loadpng.h | 8 +++++++- 11 files changed, 77 insertions(+), 15 deletions(-) diff --git a/mplot/ColourMap.h b/mplot/ColourMap.h index 19a00491..e3291009 100644 --- a/mplot/ColourMap.h +++ b/mplot/ColourMap.h @@ -1,14 +1,13 @@ module; #include // William Lenthe's implementation of perceptually uniform colour maps -//#include -//#include -//#include -//#include +#include +#include +#include +#include export module mplot.colourmap; -import std; export import :colourmaps_cet; // Colour map tables from CET export import :colourmaps_crameri; // Colour map tables from Fabio Crameri export import :colourmap_lists; // Colour map tables from matplotlib diff --git a/mplot/CoordArrows.h b/mplot/CoordArrows.h index ef3533ba..019f48ca 100644 --- a/mplot/CoordArrows.h +++ b/mplot/CoordArrows.h @@ -6,9 +6,13 @@ * \author Seb James * \date 2019 */ +module; + +#include +#include + export module mplot.coordarrows; -import std; import sm.vec; import mplot.gl.version; export import mplot.visualmodel; diff --git a/mplot/DatasetStyle.h b/mplot/DatasetStyle.h index c28de284..1013cfdf 100644 --- a/mplot/DatasetStyle.h +++ b/mplot/DatasetStyle.h @@ -1,6 +1,10 @@ +module; + +#include +#include + export module mplot.datasetstyle; -import std; import sm.vec; import sm.flags; diff --git a/mplot/ReadCurves.h b/mplot/ReadCurves.h index 6f96c6d6..de8f48bb 100644 --- a/mplot/ReadCurves.h +++ b/mplot/ReadCurves.h @@ -22,7 +22,7 @@ #include #include -//#include // for tools::searchReplace and tools::containsOnlyWhitespace + import mplot.tools; import sm.bezcurvepath; diff --git a/mplot/Visual.h b/mplot/Visual.h index 832eea28..d6e31517 100644 --- a/mplot/Visual.h +++ b/mplot/Visual.h @@ -22,9 +22,12 @@ module; # include #endif // _glfw3_h_ +#include +#include +#include + export module mplot.visual; -import std; export import mplot.gl.version; export import mplot.win_t; diff --git a/mplot/VisualCommon.h b/mplot/VisualCommon.h index 76b5ae32..c577a7ca 100644 --- a/mplot/VisualCommon.h +++ b/mplot/VisualCommon.h @@ -3,9 +3,17 @@ * * Author: Seb James. */ +module; + +#include +#include +#include +#include +#include +#include + export module mplot.visualcommon; -import std; import sm.vec; import sm.range; import sm.vvec; diff --git a/mplot/VisualDataModel.h b/mplot/VisualDataModel.h index 2b7c028d..a6da1a5c 100644 --- a/mplot/VisualDataModel.h +++ b/mplot/VisualDataModel.h @@ -1,9 +1,13 @@ /*! * VisualModels which have data. */ +module; + +#include +#include + export module mplot.visualdatamodel; -import std; import sm.vec; import sm.vvec; import sm.scale; diff --git a/mplot/VisualFace.h b/mplot/VisualFace.h index edfc7bdc..fe43db11 100644 --- a/mplot/VisualFace.h +++ b/mplot/VisualFace.h @@ -21,6 +21,11 @@ module; #include #include FT_FREETYPE_H +#include +#include +#include +#include + #include /* @@ -29,7 +34,6 @@ module; export module mplot.visualface; -import std; import mplot.visualcommon; import mplot.visualfont; import mplot.textfeatures; diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index 40b28576..3d7a65b5 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -17,9 +17,25 @@ module; # include #endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + export module mplot.visualmodel; -import std; import sm.mathconst; import sm.geometry_polyhedra; import sm.quaternion; diff --git a/mplot/graphing.h b/mplot/graphing.h index c349cad3..b27a871f 100644 --- a/mplot/graphing.h +++ b/mplot/graphing.h @@ -5,9 +5,23 @@ * Seb James * March 2025 */ +module; + +#include +#include +#include +#include +#include +#ifdef MPLOT_HAVE_STD_FORMAT +# include +#else +# include +# include +# include +#endif + export module mplot.graphing; -import std; import sm.constexpr_math; import sm.range; import sm.algo; diff --git a/mplot/loadpng.h b/mplot/loadpng.h index 4be3500b..11070266 100644 --- a/mplot/loadpng.h +++ b/mplot/loadpng.h @@ -6,9 +6,15 @@ module; #define LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS 1 #include +#include +#include +#include +#include +#include +#include + export module mplot.loadpng; -import std; export import sm.vec; import sm.vvec; From f55c43d73f8ca9592ac6236653a9c92519f1e063 Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 11:21:46 +0000 Subject: [PATCH 079/106] Comment out the C++23 import std; module stuff --- CMakeLists.txt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8404ac22..3521b10e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,8 @@ -cmake_minimum_required(VERSION 3.30) +# 3.28.5: C++20 modules support 3.30 gives C++23 import std; +cmake_minimum_required(VERSION 3.28.5) -set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444") +# For future import std; support +# set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444") project(mathplot LANGUAGES CXX C) # Note that the project version is encoded in mplot/version.h and not in this CMakeLists.txt @@ -13,10 +15,12 @@ message(STATUS " (This can be changed with `cmake -DCMAKE_INSTALL_PREFIX=/some/ # set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS ON) + +# For future import std; support +# set(CMAKE_CXX_EXTENSIONS ON) # Tell CMake that we explicitly want `import std`. This will initialize the # property on all targets declared after this to 1 -set(CMAKE_CXX_MODULE_STD 1) +# set(CMAKE_CXX_MODULE_STD 1) include(CheckIncludeFileCXX) # CHECK_INCLUDE_FILE_CXX will be used in later scripts From 17950bf7aa73054288003fa63abe02266cb0a412 Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 11:22:02 +0000 Subject: [PATCH 080/106] Correct branch of maths --- maths | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths b/maths index 6dfa56c8..5dd5485c 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit 6dfa56c84600495c579689fcef34b2261b2a310a +Subproject commit 5dd5485cf68f7481123e930fc466f6eb55a61147 From 5ee6b35bc838a95ed78a8617024311ddfd416a2d Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 11:25:31 +0000 Subject: [PATCH 081/106] Correct maths commit --- maths | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths b/maths index 5dd5485c..b686e2aa 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit 5dd5485cf68f7481123e930fc466f6eb55a61147 +Subproject commit b686e2aab8545056c404db8e69ed0064619b1d81 From eb46c9a7739fd1462a8e12f7e414952ba4e1af48 Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 12:21:38 +0000 Subject: [PATCH 082/106] Notes about my modules experience --- README.modules.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/README.modules.md b/README.modules.md index be9c0318..5f424479 100644 --- a/README.modules.md +++ b/README.modules.md @@ -1,4 +1,60 @@ -# Modules build times +# Modules builds + +## Motivation + +Around March 2026 I wanted to try to improve the 35 second build time of a project I was working on. +I was aware of C++ modules as a way to automate the building of an otherwise header-only codebase like mathplot. +I gave it a try, first in sebsjames/maths, and then in mathplot. + +I was originally buildling the project with gcc 13 or gcc 14, and linking a library containing CUDA and OptiX code, which was compiled with gcc 12 and CUDA's nvcc. The build time was about 35 seconds, regardless of which source code file I changed and of how trivial that change was. + +Before starting I looked at compilers you'd need to build C++20 modules. Documentation suggested clang-18 or gcc-14 (but really 15) would be minimal requirements. +With gcc 15 soon to be available in a standard Ubuntu download and clang-18 already there, I decided it was worth the time making the code changes. + +The first stage was to convert to basic C++20 modules, where I would only make modules out of my own code, and continue to use `#include ` rather than `import std;` or `import ;`. + +There were several tasks + +* Switch from building with cmake/Makefiles to cmake/Ninja. Add the new incantations to recognise modules files and compile these. +* Remove all circular dependencies from the code - there was a fundamental one in mathplot's core which required an architectural redesign (this is a real improvement). +* Switch from header-only glad to glad as a compiled library (I did consider trying to make a 'glad module' but wasn't sure it would work; the glad project doesn't have a generator for 'modularized glad') +* Make a library of the mathplot fonts to link to the executable (previously, the asm calls were header-only) +* Learn the new kind of error messages and how to understand them. +* Edit all the files to export and import modules. +* Ensure I was using modules-compatible versions of third party libraries (nlohman-json) +* Remove any non-modules compatible third party library links that I could (armadillo) +* Re-write my Bezier curve code to use `sm::mat` instead of `arma::Mat` +* Add stuff to `sm::mat` as part of the thing above (and fix some bugs) +* Report several bugs to gcc, as gcc-15 was falling over on some of my C++ once it was encapsulated in a module + +All this work took about 2 weeks. + +I discovered that the minimum compiler versions are practically clang-20 and gcc-master (with some bugs still to be resolved). + +I discovered that, had I switched to clang-20 with my original header-only code, I could have improved my build times from 35 s to 20-ish seconds! + +However, my re-build time on the complex project is down to less than 10 seconds, so the work was worthwhile. + +### Stage 2 `import std;` + +C++23 `import std;` is available with clang-20 and gcc-15. CMake supports it too. I figured I may as well move to `import std;` along with my C++20 `sm.` and `mplot.` modules. + +This involved: + +* Learning how to ensure that the toolchain would build the std.* library module. Crucially, I had to pass the correct library (libc++ for clang-20) on the cmake command line. Some lines had to change in CMakeLists.txt, too. +* Switching all use of `size_t` to the fully qualified `std::size_t` and `uint32_t` and similar from `cstdint` to `std::uint32_t` (alternatively, I could have used `import std.compat`). + +I got this working over a weekend and built both maths tests and mathplot examples with `import std;`. + +However, with the more complex project, I discovered a gotcha. If you link another compiled C++ library (compound-ray) then it has to be compiled with a binary compatible libc++. +With `import std;` I got best results with libc++, but compound-ray compiles with libstdc++. + +I think this can be made to work, but I will either have to: + +* Update the compound-ray build process to build with CUDA-13, which is clang-20 compatible +* Make the compound-ray API pure C (right now I'm using a C++ data structure to transfer data + +For now, I'm sticking with regular C++20 modules, because the addition of `import std;` doesn't make that much difference to compile times. ## Matplot examples From a7c4835f727058731b610a137ebc11a411fb13ac Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 13:15:57 +0000 Subject: [PATCH 083/106] Changes to modules readme --- README.modules.md | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/README.modules.md b/README.modules.md index 5f424479..cc1b1f55 100644 --- a/README.modules.md +++ b/README.modules.md @@ -2,20 +2,25 @@ ## Motivation -Around March 2026 I wanted to try to improve the 35 second build time of a project I was working on. +Around March 2026 I wanted to try to improve the 35 second build time of [a project](https://github.com/sebsjames/antpov) I was working on. + +I was originally building the project with gcc-13 (and sometimes gcc-14), and linking the library [compound-ray](https://github.com/sebsjames/compound-ray)) containing CUDA and OptiX code, which was compiled with gcc-12 and CUDA's nvcc. +The build time was about 35 seconds, regardless of which source code file I changed and of how trivial that change was. + I was aware of C++ modules as a way to automate the building of an otherwise header-only codebase like mathplot. -I gave it a try, first in sebsjames/maths, and then in mathplot. +I was interested to give it a try with the hope that it would speed up re-build times for my project. -I was originally buildling the project with gcc 13 or gcc 14, and linking a library containing CUDA and OptiX code, which was compiled with gcc 12 and CUDA's nvcc. The build time was about 35 seconds, regardless of which source code file I changed and of how trivial that change was. +Before starting I looked at compilers you'd need to build C++20 modules. Documentation suggested clang-18 or gcc-14 (but really 15) would be minimal requirements, along with cmake at about version 28 from late 2023. +With gcc-15 soon to be available in a standard Ubuntu download, and clang-18 and cmake 28 both available in Ubuntu 24.04, I decided that the module-supporting toolchains were available and it was worth the time making the code changes. -Before starting I looked at compilers you'd need to build C++20 modules. Documentation suggested clang-18 or gcc-14 (but really 15) would be minimal requirements. -With gcc 15 soon to be available in a standard Ubuntu download and clang-18 already there, I decided it was worth the time making the code changes. +### Stage 1 C++20 modules The first stage was to convert to basic C++20 modules, where I would only make modules out of my own code, and continue to use `#include ` rather than `import std;` or `import ;`. There were several tasks * Switch from building with cmake/Makefiles to cmake/Ninja. Add the new incantations to recognise modules files and compile these. +* Discover that the real minimum version for C++20 modules is [cmake 3.28.5](https://discourse.cmake.org/t/how-can-i-be-sure-that-a-c-20-module-is-not-re-compiled-after-a-non-module-code-change/15535). * Remove all circular dependencies from the code - there was a fundamental one in mathplot's core which required an architectural redesign (this is a real improvement). * Switch from header-only glad to glad as a compiled library (I did consider trying to make a 'glad module' but wasn't sure it would work; the glad project doesn't have a generator for 'modularized glad') * Make a library of the mathplot fonts to link to the executable (previously, the asm calls were header-only) @@ -25,16 +30,10 @@ There were several tasks * Remove any non-modules compatible third party library links that I could (armadillo) * Re-write my Bezier curve code to use `sm::mat` instead of `arma::Mat` * Add stuff to `sm::mat` as part of the thing above (and fix some bugs) -* Report several bugs to gcc, as gcc-15 was falling over on some of my C++ once it was encapsulated in a module +* Report several bugs to gcc, as gcc-15 was falling over on some of my C++ once it was encapsulated in a module: [124430](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124430) [124431](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124431) [124466](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124466) [124470](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124470) [124483](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124483) All this work took about 2 weeks. -I discovered that the minimum compiler versions are practically clang-20 and gcc-master (with some bugs still to be resolved). - -I discovered that, had I switched to clang-20 with my original header-only code, I could have improved my build times from 35 s to 20-ish seconds! - -However, my re-build time on the complex project is down to less than 10 seconds, so the work was worthwhile. - ### Stage 2 `import std;` C++23 `import std;` is available with clang-20 and gcc-15. CMake supports it too. I figured I may as well move to `import std;` along with my C++20 `sm.` and `mplot.` modules. @@ -56,9 +55,16 @@ I think this can be made to work, but I will either have to: For now, I'm sticking with regular C++20 modules, because the addition of `import std;` doesn't make that much difference to compile times. -## Matplot examples +## What I learned + +* The minimum compiler versions are practically clang-20 and gcc-master (with some bugs still to be resolved, though I DID get most of the mathplot examples to build). +* Had I switched to clang-20 with my original header-only code, I could have improved my build times from 35 s to 20-ish seconds! +* The modules build process reduces the re-build time on the complex project to less than 10 seconds, so the work was worthwhile. +* Using `import std;` can lead to complex linking issues + +## Matplot example profiling -The examples built were: +Here's a profile of build times for mathplot examples. The examples built were: ``` breadcrumbs cray_eye ellipsoid geodesic graph1 grid_simple helloworld hexgrid rod rod_with_normals showcase vectorvis @@ -95,7 +101,7 @@ All examples from scratch: 19 s breadcrumbs rebuild time after touch breadcrumbs.cpp (rebuilds 4 items): 6.9 s breadcrumbs rebuild time after touch VisualModel (rebuilds 130 items): 6.9 s -## Complex example +## Profiling the complex example Test machine: Scan desktop, Intel(R) Core(TM) Ultra 9 285K @@ -109,7 +115,7 @@ CC=clang-20 CXX=clang++-20 cmake .. -G Ninja -DOptiX_INSTALL_DIR=~/src/NVIDIA-Op Build antpov from scratch (138 items): 26.3 s -Build after touch antpov.cpp: 8.9 s +Build after touch antpov.cpp: 8.9 s ### With `import std;` From c2e9da715d036171f288147bb26911b3c91e823b Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 13:19:35 +0000 Subject: [PATCH 084/106] More modules readme tweaks --- README.modules.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/README.modules.md b/README.modules.md index cc1b1f55..5a263b4b 100644 --- a/README.modules.md +++ b/README.modules.md @@ -10,8 +10,8 @@ The build time was about 35 seconds, regardless of which source code file I chan I was aware of C++ modules as a way to automate the building of an otherwise header-only codebase like mathplot. I was interested to give it a try with the hope that it would speed up re-build times for my project. -Before starting I looked at compilers you'd need to build C++20 modules. Documentation suggested clang-18 or gcc-14 (but really 15) would be minimal requirements, along with cmake at about version 28 from late 2023. -With gcc-15 soon to be available in a standard Ubuntu download, and clang-18 and cmake 28 both available in Ubuntu 24.04, I decided that the module-supporting toolchains were available and it was worth the time making the code changes. +Before starting I looked at compilers you'd need to build C++20 modules. Documentation suggested clang-18 or gcc-14 (but really 15) would be minimal requirements, along with cmake at about version 3.28 from late 2023. +With gcc-15 soon to be available in a standard Ubuntu download, and clang-18 and cmake 3.28 both available in Ubuntu 24.04, I decided that the module-supporting toolchains were available and it was worth the time making the code changes. ### Stage 1 C++20 modules @@ -82,24 +82,30 @@ CC=clang-20 CXX=clang++-20 cmake .. -G Ninja -DCMAKE_CXX_FLAGS=-stdlib=libc++ Building with *full* modules, including import std; +``` All examples from scratch: 42-46 sec, (13min user time) breadcrumbs rebuild time after touch breadcrumbs.cpp (rebuilds 4 items): 5.8 s breadcrumbs rebuild time after touch VisualModel (rebuilds 130 items): 24.0 s +``` ### Without `import std;` +``` All examples from scratch: 74 s breadcrumbs rebuild time after touch breadcrumbs.cpp: 5.9 s breadcrumbs rebuild time after touch VisualModel (rebuilds 11 items): 17.6 s +``` ### Header only +``` All examples from scratch: 19 s breadcrumbs rebuild time after touch breadcrumbs.cpp (rebuilds 4 items): 6.9 s breadcrumbs rebuild time after touch VisualModel (rebuilds 130 items): 6.9 s +``` ## Profiling the complex example @@ -113,20 +119,26 @@ CC=clang-20 CXX=clang++-20 cmake .. -G Ninja -DOptiX_INSTALL_DIR=~/src/NVIDIA-Op ### Without `import std;` +``` Build antpov from scratch (138 items): 26.3 s Build after touch antpov.cpp: 8.9 s +``` ### With `import std;` Note that the final link does not complete at present, but I think these times are representative +``` Build antpov from scratch (150 items): 19.5 s Build after touch antpov.cpp (4 items): 7.6 s +``` ## Header only +``` Build antpov from scratch (2 items): 17.4 s Build after touch antpov.cpp (2 items): 17.4 s +``` \ No newline at end of file From aab53ae1fca602b17880844f8460fd9a9cd5fc40 Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 13:26:10 +0000 Subject: [PATCH 085/106] More notes and links --- README.modules.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.modules.md b/README.modules.md index 5a263b4b..981e1419 100644 --- a/README.modules.md +++ b/README.modules.md @@ -20,7 +20,7 @@ The first stage was to convert to basic C++20 modules, where I would only make m There were several tasks * Switch from building with cmake/Makefiles to cmake/Ninja. Add the new incantations to recognise modules files and compile these. -* Discover that the real minimum version for C++20 modules is [cmake 3.28.5](https://discourse.cmake.org/t/how-can-i-be-sure-that-a-c-20-module-is-not-re-compiled-after-a-non-module-code-change/15535). +* Discover that the real minimum version for C++20 modules is [cmake 3.28.5](https://discourse.cmake.org/t/how-can-i-be-sure-that-a-c-20-module-is-not-re-compiled-after-a-non-module-code-change/15535). Prior to this version, your modules would *build* but a re-build would cause *all* the modules to rebuild, and thus give you no build-time speed up! * Remove all circular dependencies from the code - there was a fundamental one in mathplot's core which required an architectural redesign (this is a real improvement). * Switch from header-only glad to glad as a compiled library (I did consider trying to make a 'glad module' but wasn't sure it would work; the glad project doesn't have a generator for 'modularized glad') * Make a library of the mathplot fonts to link to the executable (previously, the asm calls were header-only) @@ -40,7 +40,7 @@ C++23 `import std;` is available with clang-20 and gcc-15. CMake supports it too This involved: -* Learning how to ensure that the toolchain would build the std.* library module. Crucially, I had to pass the correct library (libc++ for clang-20) on the cmake command line. Some lines had to change in CMakeLists.txt, too. +* Learning how to ensure that the toolchain would build the std.* library module. Crucially, [I had to pass the correct runtime library](https://discourse.cmake.org/t/having-difficulty-compiling-with-import-std-support-cmake-cant-build-std-cppm/15557) (libc++ for clang-20) on the cmake command line. Some lines had to change in CMakeLists.txt, too. * Switching all use of `size_t` to the fully qualified `std::size_t` and `uint32_t` and similar from `cstdint` to `std::uint32_t` (alternatively, I could have used `import std.compat`). I got this working over a weekend and built both maths tests and mathplot examples with `import std;`. @@ -58,9 +58,11 @@ For now, I'm sticking with regular C++20 modules, because the addition of `impor ## What I learned * The minimum compiler versions are practically clang-20 and gcc-master (with some bugs still to be resolved, though I DID get most of the mathplot examples to build). +* Make sure to use cmake 3.28.5 or higher (I've been using the latest release, 4.2.x). * Had I switched to clang-20 with my original header-only code, I could have improved my build times from 35 s to 20-ish seconds! * The modules build process reduces the re-build time on the complex project to less than 10 seconds, so the work was worthwhile. -* Using `import std;` can lead to complex linking issues +* Using C++20 modules will require that any third-party header-only code you're using is modules compatible - this just means avoiding a few small things like the `static` keyword on namespaced functions, but if your third-party library needs patching, it's an additional level of complexity. +* Using `import std;` can lead to complex linking issues, so evaluate your third party libraries carefully. ## Matplot example profiling From 03ce4f71c2e0e0fa15df20686d3ef2efeec25779 Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 13:27:24 +0000 Subject: [PATCH 086/106] Title --- README.modules.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.modules.md b/README.modules.md index 981e1419..8e7f7bfd 100644 --- a/README.modules.md +++ b/README.modules.md @@ -1,6 +1,4 @@ -# Modules builds - -## Motivation +# C++ Modules Around March 2026 I wanted to try to improve the 35 second build time of [a project](https://github.com/sebsjames/antpov) I was working on. From 9a29d48b29a34a0936c6bc124e0da76d55b4a6ea Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 13:30:49 +0000 Subject: [PATCH 087/106] What I'll do now --- README.modules.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.modules.md b/README.modules.md index 8e7f7bfd..47f7bbed 100644 --- a/README.modules.md +++ b/README.modules.md @@ -62,6 +62,12 @@ For now, I'm sticking with regular C++20 modules, because the addition of `impor * Using C++20 modules will require that any third-party header-only code you're using is modules compatible - this just means avoiding a few small things like the `static` keyword on namespaced functions, but if your third-party library needs patching, it's an additional level of complexity. * Using `import std;` can lead to complex linking issues, so evaluate your third party libraries carefully. +## What I will do now + +For now, I'm going to work with dev/modules branches on [mathplot](https://github.com/sebsjames/mathplot/tree/dev/modules) and [maths](https://github.com/sebsjames/maths/tree/dev/modules). + +I still need to convert all the mathplot examples and **mplot/** code to modules. When it had matured enough, I'll merge it into main. C++ modules are coming for mathplot and maths... + ## Matplot example profiling Here's a profile of build times for mathplot examples. The examples built were: From ecfbe9a05ac8bb000c09a05c78237ce26468f876 Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 17 Mar 2026 13:33:15 +0000 Subject: [PATCH 088/106] Last changes to readme modules --- README.modules.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.modules.md b/README.modules.md index 47f7bbed..ab0f2f4f 100644 --- a/README.modules.md +++ b/README.modules.md @@ -66,7 +66,11 @@ For now, I'm sticking with regular C++20 modules, because the addition of `impor For now, I'm going to work with dev/modules branches on [mathplot](https://github.com/sebsjames/mathplot/tree/dev/modules) and [maths](https://github.com/sebsjames/maths/tree/dev/modules). -I still need to convert all the mathplot examples and **mplot/** code to modules. When it had matured enough, I'll merge it into main. C++ modules are coming for mathplot and maths... +I still need to convert all the mathplot examples and **mplot/** code to modules. Once I've completed the conversion, and when it has matured enough, I'll merge the modules code into main. + +I've made several significant improvements to the codebase as a result of this work, which would have to be backported if I wanted to abandon modules and stick with header only. + +However, I think that C++ modules are coming for mathplot and maths. ## Matplot example profiling From 1e1a7a07bdd6966a503af267dbc332edd657a3f6 Mon Sep 17 00:00:00 2001 From: Seb James Date: Wed, 18 Mar 2026 14:52:26 +0000 Subject: [PATCH 089/106] Splits Ommatidium definition into its own little module --- examples/CMakeLists.txt | 1 + mplot/compoundray/EyeVisual.h | 11 +---------- mplot/compoundray/Ommatidium.h | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 mplot/compoundray/Ommatidium.h diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 54b552a4..ea74acaa 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -53,6 +53,7 @@ set(MPLOT_CORE_MODULES ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h ${PROJECT_SOURCE_DIR}/mplot/DatasetStyle.h ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.h + ${PROJECT_SOURCE_DIR}/mplot/compoundray/Ommatidium.h ) # Maths used in individual VisualModels, but not the mathplot core diff --git a/mplot/compoundray/EyeVisual.h b/mplot/compoundray/EyeVisual.h index 2202f463..bca7cb74 100644 --- a/mplot/compoundray/EyeVisual.h +++ b/mplot/compoundray/EyeVisual.h @@ -18,20 +18,11 @@ import sm.centroid; export import mplot.gl.version; export import mplot.visualmodel; +export import mplot.compoundray.ommatidium; import mplot.tools; export namespace mplot::compoundray { - // This is a binary-compatible equivalent to struct Ommatidium from cameras/CompoundEyeDataTypes.h in compound-ray. - // Use reinterpret_cast*>(ommatidia) if your ommatidia originate inside compound ray. - struct Ommatidium - { - sm::vec relativePosition = {}; - sm::vec relativeDirection = {}; - float acceptanceAngleRadians = 0.0f; - float focalPointOffset = 0.0f; - }; - // Helper function. Read the compound-ray csv eye file into ommatidia. ommatidia should be a pointer to an allocate vector. [[maybe_unused]] std::vector* readEye (std::vector* ommatidia, const std::string& path) diff --git a/mplot/compoundray/Ommatidium.h b/mplot/compoundray/Ommatidium.h new file mode 100644 index 00000000..528fcdba --- /dev/null +++ b/mplot/compoundray/Ommatidium.h @@ -0,0 +1,19 @@ +/* + * A mathplot native version of compound-ray's Ommatidium + */ +export module mplot.compoundray.ommatidium; + +export import sm.vec; + +export namespace mplot::compoundray +{ + // This is a binary-compatible equivalent to struct Ommatidium from cameras/CompoundEyeDataTypes.h in compound-ray. + // Use reinterpret_cast*>(ommatidia) if your ommatidia originate inside compound ray. + struct Ommatidium + { + sm::vec relativePosition = {}; + sm::vec relativeDirection = {}; + float acceptanceAngleRadians = 0.0f; + float focalPointOffset = 0.0f; + }; +} From d7063c58777d5cab24cf714ed01c4378eafbca80 Mon Sep 17 00:00:00 2001 From: Seb James Date: Thu, 19 Mar 2026 14:36:41 +0000 Subject: [PATCH 090/106] Latest maths, incl an update to hdfdata --- maths | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths b/maths index b686e2aa..36fb8cd4 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit b686e2aab8545056c404db8e69ed0064619b1d81 +Subproject commit 36fb8cd4ffda598cb1869ee03176de939d8ac845 From 117e1b59cf54913d463d6aea77b3fbe3e0ac7fe4 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 20 Mar 2026 16:32:23 +0000 Subject: [PATCH 091/106] Use updated module names from maths (.cppm suffix) --- CMakeLists.txt | 56 +++++++++++++-------------- examples/CMakeLists.txt | 86 ++++++++++++++++++++--------------------- maths | 2 +- 3 files changed, 72 insertions(+), 72 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3521b10e..07f08b5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -187,16 +187,16 @@ endif() # else we have it in a directory included by default in the path # sebsjames/maths module groups # set(SM_CONSTEXPR_MATH_MODULES - ${PROJECT_SOURCE_DIR}/sm/mathconst - ${PROJECT_SOURCE_DIR}/sm/constexpr_math + ${PROJECT_SOURCE_DIR}/sm/mathconst.cppm + ${PROJECT_SOURCE_DIR}/sm/constexpr_math.cppm ) set(SM_POLYSOLVE_MODULES ${SM_CONSTEXPR_MATH_MODULES} - ${PROJECT_SOURCE_DIR}/sm/polysolve + ${PROJECT_SOURCE_DIR}/sm/polysolve.cppm ) set(SM_BESSEL_I0_MODULES ${SM_POLYSOLVE_MODULES} - ${PROJECT_SOURCE_DIR}/sm/bessel_i0 + ${PROJECT_SOURCE_DIR}/sm/bessel_i0.cppm ) set(SM_RANDOM_MODULES ${SM_BESSEL_I0_MODULES} @@ -204,102 +204,102 @@ set(SM_RANDOM_MODULES ) set(SM_RANGE_MODULES ${SM_CONSTEXPR_MATH_MODULES} - ${PROJECT_SOURCE_DIR}/sm/trait_tests - ${PROJECT_SOURCE_DIR}/sm/range + ${PROJECT_SOURCE_DIR}/sm/trait_tests.cppm + ${PROJECT_SOURCE_DIR}/sm/range.cppm ) set(SM_VEC_MODULES ${SM_RANGE_MODULES} ${SM_RANDOM_MODULES} - ${PROJECT_SOURCE_DIR}/sm/vec + ${PROJECT_SOURCE_DIR}/sm/vec.cppm ) set(SM_VVEC_MODULES ${SM_RANGE_MODULES} ${SM_RANDOM_MODULES} - ${PROJECT_SOURCE_DIR}/sm/vvec + ${PROJECT_SOURCE_DIR}/sm/vvec.cppm ) set(SM_SCALE_MODULES ${SM_VVEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/scale + ${PROJECT_SOURCE_DIR}/sm/scale.cppm ) set(SM_UTIL_MODULES - ${PROJECT_SOURCE_DIR}/sm/trait_tests - ${PROJECT_SOURCE_DIR}/sm/util + ${PROJECT_SOURCE_DIR}/sm/trait_tests.cppm + ${PROJECT_SOURCE_DIR}/sm/util.cppm ) set(SM_HDFDATA_MODULES ${SM_VEC_MODULES} ${SM_VVEC_MODULES} ${SM_UTIL_MODULES} - ${PROJECT_SOURCE_DIR}/sm/hdfdata + ${PROJECT_SOURCE_DIR}/sm/hdfdata.cppm ) set(SM_QUATERNION_MODULES ${SM_VEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/quaternion + ${PROJECT_SOURCE_DIR}/sm/quaternion.cppm ) set(SM_MAT_MODULES ${SM_QUATERNION_MODULES} - ${PROJECT_SOURCE_DIR}/sm/mat + ${PROJECT_SOURCE_DIR}/sm/mat.cppm ) set(SM_BEZCOORD_MODULES ${SM_VEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/bezcoord + ${PROJECT_SOURCE_DIR}/sm/bezcoord.cppm ) set(SM_HEX_MODULES ${SM_BEZCOORD_MODULES} - ${PROJECT_SOURCE_DIR}/sm/hex + ${PROJECT_SOURCE_DIR}/sm/hex.cppm ) set(SM_WINDER_MODULES ${SM_VEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/winder + ${PROJECT_SOURCE_DIR}/sm/winder.cppm ) set(SM_BOOTSTRAP_MODULES ${SM_VEC_MODULES} ${SM_VVEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/bootstrap + ${PROJECT_SOURCE_DIR}/sm/bootstrap.cppm ) set(SM_GRID_MODULES ${SM_VEC_MODULES} ${SM_VVEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/grid + ${PROJECT_SOURCE_DIR}/sm/grid.cppm ) set(SM_ALGO_MODULES ${SM_VEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/algo + ${PROJECT_SOURCE_DIR}/sm/algo.cppm ) set(SM_NM_SIMPLEX_MODULES ${SM_ALGO_MODULES} ${SM_VVEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/nm_simplex + ${PROJECT_SOURCE_DIR}/sm/nm_simplex.cppm ) set(SM_HISTO_MODULES ${SM_VEC_MODULES} ${SM_VVEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/histo + ${PROJECT_SOURCE_DIR}/sm/histo.cppm ) set(SM_BOXFILTER_MODULES ${SM_VEC_MODULES} ${SM_VVEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/boxfilter + ${PROJECT_SOURCE_DIR}/sm/boxfilter.cppm ) set(SM_GEOMETRY_MODULES ${SM_ALGO_MODULES} ${SM_VVEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/geometry + ${PROJECT_SOURCE_DIR}/sm/geometry.cppm ) set(SM_BEZCURVE_MODULES ${SM_BEZCOORD_MODULES} ${SM_MAT_MODULES} ${SM_NM_SIMPLEX_MODULES} - ${PROJECT_SOURCE_DIR}/sm/binomial - ${PROJECT_SOURCE_DIR}/sm/bezcurve + ${PROJECT_SOURCE_DIR}/sm/binomial.cppm + ${PROJECT_SOURCE_DIR}/sm/bezcurve.cppm ) set(SM_BEZCURVEPATH_MODULES ${SM_BEZCURVE_MODULES} - ${PROJECT_SOURCE_DIR}/sm/bezcurvepath + ${PROJECT_SOURCE_DIR}/sm/bezcurvepath.cppm ) set(SM_HEXGRID_MODULES ${SM_BEZCURVEPATH_MODULES} ${SM_HEX_MODULES} - ${PROJECT_SOURCE_DIR}/sm/hexgrid + ${PROJECT_SOURCE_DIR}/sm/hexgrid.cppm ) # All the mathplot headers are here diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ea74acaa..5b7f61ac 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -2,26 +2,26 @@ include_directories(BEFORE ${PROJECT_SOURCE_DIR}) set(SM_CORE_MODULES - ${PROJECT_SOURCE_DIR}/maths/sm/mathconst - ${PROJECT_SOURCE_DIR}/maths/sm/constexpr_math - ${PROJECT_SOURCE_DIR}/maths/sm/range - ${PROJECT_SOURCE_DIR}/maths/sm/polysolve - ${PROJECT_SOURCE_DIR}/maths/sm/bessel_i0 - ${PROJECT_SOURCE_DIR}/maths/sm/random - ${PROJECT_SOURCE_DIR}/maths/sm/vec - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion - ${PROJECT_SOURCE_DIR}/maths/sm/mat - ${PROJECT_SOURCE_DIR}/maths/sm/trait_tests - ${PROJECT_SOURCE_DIR}/maths/sm/util - ${PROJECT_SOURCE_DIR}/maths/sm/base64 - ${PROJECT_SOURCE_DIR}/maths/sm/crc32 - ${PROJECT_SOURCE_DIR}/maths/sm/flags - ${PROJECT_SOURCE_DIR}/maths/sm/algo - ${PROJECT_SOURCE_DIR}/maths/sm/geometry - ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra - ${PROJECT_SOURCE_DIR}/maths/sm/vvec - ${PROJECT_SOURCE_DIR}/maths/sm/scale - ${PROJECT_SOURCE_DIR}/maths/sm/centroid + ${PROJECT_SOURCE_DIR}/maths/sm/mathconst.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/constexpr_math.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/range.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/polysolve.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/bessel_i0.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/random.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/vec.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/quaternion.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/mat.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/trait_tests.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/util.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/base64.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/crc32.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/flags.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/algo.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/geometry.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/vvec.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/scale.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/centroid.cppm ) # Base modules for mathplot set(MPLOT_CORE_MODULES @@ -58,27 +58,27 @@ set(MPLOT_CORE_MODULES # Maths used in individual VisualModels, but not the mathplot core set(SM_VISUALMODEL_MODULES - ${PROJECT_SOURCE_DIR}/maths/sm/winder - ${PROJECT_SOURCE_DIR}/maths/sm/histo - ${PROJECT_SOURCE_DIR}/maths/sm/grid - ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex - ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord - ${PROJECT_SOURCE_DIR}/maths/sm/binomial - ${PROJECT_SOURCE_DIR}/maths/sm/bezcurve - ${PROJECT_SOURCE_DIR}/maths/sm/bezcurvepath - ${PROJECT_SOURCE_DIR}/maths/sm/hex - ${PROJECT_SOURCE_DIR}/maths/sm/hexgrid + ${PROJECT_SOURCE_DIR}/maths/sm/winder.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/histo.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/grid.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/binomial.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/bezcurve.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/bezcurvepath.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/hex.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/hexgrid.cppm ) # The modules required for hexgrids set(SM_HEXGRID_MODULES - ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex - ${PROJECT_SOURCE_DIR}/maths/sm/binomial - ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord - ${PROJECT_SOURCE_DIR}/maths/sm/bezcurve - ${PROJECT_SOURCE_DIR}/maths/sm/bezcurvepath - ${PROJECT_SOURCE_DIR}/maths/sm/hex - ${PROJECT_SOURCE_DIR}/maths/sm/hexgrid + ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/binomial.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/bezcurve.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/bezcurvepath.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/hex.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/hexgrid.cppm ) set(MPLOT_VISUALMODEL_MODULES @@ -153,7 +153,7 @@ target_sources(cray_eye PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_D FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/SphereVisual.h ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.h - ${PROJECT_SOURCE_DIR}/maths/sm/winder + ${PROJECT_SOURCE_DIR}/maths/sm/winder.cppm ${PROJECT_SOURCE_DIR}/mplot/compoundray/EyeVisual.h ) target_link_libraries(cray_eye OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) @@ -161,8 +161,8 @@ target_link_libraries(cray_eye OpenGL::GL glfw Freetype::Freetype glad mplot_fon add_executable(graph1 graph1.cpp) target_sources(graph1 PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} - ${PROJECT_SOURCE_DIR}/maths/sm/histo - ${PROJECT_SOURCE_DIR}/maths/sm/grid + ${PROJECT_SOURCE_DIR}/maths/sm/histo.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/grid.cppm ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h ) target_link_libraries(graph1 OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) @@ -171,7 +171,7 @@ target_link_libraries(graph1 OpenGL::GL glfw Freetype::Freetype glad mplot_fontd add_executable(grid_simple grid_simple.cpp) target_sources(grid_simple PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} - ${PROJECT_SOURCE_DIR}/maths/sm/grid + ${PROJECT_SOURCE_DIR}/maths/sm/grid.cppm ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h ) target_link_libraries(grid_simple OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) @@ -194,9 +194,9 @@ target_sources(showcase PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_D ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.h ${PROJECT_SOURCE_DIR}/mplot/TriaxesVisual.h ${PROJECT_SOURCE_DIR}/mplot/ScatterVisual.h - ${PROJECT_SOURCE_DIR}/maths/sm/grid + ${PROJECT_SOURCE_DIR}/maths/sm/grid.cppm ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h - ${PROJECT_SOURCE_DIR}/maths/sm/histo + ${PROJECT_SOURCE_DIR}/maths/sm/histo.cppm ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h ) target_link_libraries(showcase OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) diff --git a/maths b/maths index 36fb8cd4..2c10dddc 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit 36fb8cd4ffda598cb1869ee03176de939d8ac845 +Subproject commit 2c10dddc6844b12259f0df5669e770d19ba7b543 From 56526bdf0568e25f5819a1fbef4d90d95c038b3e Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 20 Mar 2026 16:51:03 +0000 Subject: [PATCH 092/106] Convert modules to .cppm suffix --- examples/CMakeLists.txt | 124 +++++++++--------- ...ColourBarVisual.h => ColourBarVisual.cppm} | 0 mplot/{ColourMap.h => ColourMap.cppm} | 0 ...ColourMap_Lists.h => ColourMap_Lists.cppm} | 0 mplot/{CoordArrows.h => CoordArrows.cppm} | 0 ...rvyTellyVisual.h => CurvyTellyVisual.cppm} | 0 ...ColourVisual.h => CyclicColourVisual.cppm} | 0 mplot/{DatasetStyle.h => DatasetStyle.cppm} | 0 .../{GeodesicVisual.h => GeodesicVisual.cppm} | 0 mplot/{GraphVisual.h => GraphVisual.cppm} | 0 mplot/{GratingVisual.h => GratingVisual.cppm} | 0 mplot/{GridVisual.h => GridVisual.cppm} | 0 .../{HSVWheelVisual.h => HSVWheelVisual.cppm} | 0 mplot/{HexGridVisual.h => HexGridVisual.cppm} | 0 mplot/{IcosaVisual.h => IcosaVisual.cppm} | 0 ...erVisual.h => InstancedScatterVisual.cppm} | 0 ...thscaleVisual.h => LengthscaleVisual.cppm} | 0 mplot/{NavMesh.h => NavMesh.cppm} | 0 mplot/{NormalsVisual.h => NormalsVisual.cppm} | 0 mplot/{PolarVisual.h => PolarVisual.cppm} | 0 mplot/{QuiverVisual.h => QuiverVisual.cppm} | 0 ...RectangleVisual.h => RectangleVisual.cppm} | 0 mplot/{RhomboVisual.h => RhomboVisual.cppm} | 0 mplot/{RodVisual.h => RodVisual.cppm} | 0 mplot/{ScatterVisual.h => ScatterVisual.cppm} | 0 mplot/{SphereVisual.h => SphereVisual.cppm} | 0 ...isual.h => SphericalProjectionVisual.cppm} | 0 mplot/{TextFeatures.h => TextFeatures.cppm} | 0 mplot/{TextGeometry.h => TextGeometry.cppm} | 0 mplot/{TriaxesVisual.h => TriaxesVisual.cppm} | 0 mplot/{VectorVisual.h => VectorVisual.cppm} | 0 .../{VerticesVisual.h => VerticesVisual.cppm} | 0 mplot/{Visual.h => Visual.cppm} | 0 mplot/{VisualCommon.h => VisualCommon.cppm} | 0 ...VisualDataModel.h => VisualDataModel.cppm} | 0 mplot/{VisualFace.h => VisualFace.cppm} | 0 mplot/{VisualFont.h => VisualFont.cppm} | 0 mplot/{VisualGlfw.h => VisualGlfw.cppm} | 0 mplot/{VisualModel.h => VisualModel.cppm} | 0 mplot/{VisualOwnable.h => VisualOwnable.cppm} | 0 ...VisualResources.h => VisualResources.cppm} | 0 ...VisualTextModel.h => VisualTextModel.cppm} | 0 mplot/{colour.h => colour.cppm} | 0 .../{colourmaps_cet.h => colourmaps_cet.cppm} | 0 ...maps_crameri.h => colourmaps_crameri.cppm} | 0 .../{EyeVisual.h => EyeVisual.cppm} | 0 .../{Ommatidium.h => Ommatidium.cppm} | 0 mplot/compoundray/{interop.h => interop.cppm} | 0 mplot/fps/{profiler.h => profiler.cppm} | 0 mplot/gl/{util_mx.h => util_mx.cppm} | 0 mplot/gl/{version.h => version.cppm} | 0 mplot/{graphing.h => graphing.cppm} | 0 mplot/{graphstyles.h => graphstyles.cppm} | 0 mplot/{loadpng.h => loadpng.cppm} | 0 mplot/{tools.h => tools.cppm} | 0 mplot/{unicode.h => unicode.cppm} | 0 mplot/{win_t.h => win_t.cppm} | 0 57 files changed, 62 insertions(+), 62 deletions(-) rename mplot/{ColourBarVisual.h => ColourBarVisual.cppm} (100%) rename mplot/{ColourMap.h => ColourMap.cppm} (100%) rename mplot/{ColourMap_Lists.h => ColourMap_Lists.cppm} (100%) rename mplot/{CoordArrows.h => CoordArrows.cppm} (100%) rename mplot/{CurvyTellyVisual.h => CurvyTellyVisual.cppm} (100%) rename mplot/{CyclicColourVisual.h => CyclicColourVisual.cppm} (100%) rename mplot/{DatasetStyle.h => DatasetStyle.cppm} (100%) rename mplot/{GeodesicVisual.h => GeodesicVisual.cppm} (100%) rename mplot/{GraphVisual.h => GraphVisual.cppm} (100%) rename mplot/{GratingVisual.h => GratingVisual.cppm} (100%) rename mplot/{GridVisual.h => GridVisual.cppm} (100%) rename mplot/{HSVWheelVisual.h => HSVWheelVisual.cppm} (100%) rename mplot/{HexGridVisual.h => HexGridVisual.cppm} (100%) rename mplot/{IcosaVisual.h => IcosaVisual.cppm} (100%) rename mplot/{InstancedScatterVisual.h => InstancedScatterVisual.cppm} (100%) rename mplot/{LengthscaleVisual.h => LengthscaleVisual.cppm} (100%) rename mplot/{NavMesh.h => NavMesh.cppm} (100%) rename mplot/{NormalsVisual.h => NormalsVisual.cppm} (100%) rename mplot/{PolarVisual.h => PolarVisual.cppm} (100%) rename mplot/{QuiverVisual.h => QuiverVisual.cppm} (100%) rename mplot/{RectangleVisual.h => RectangleVisual.cppm} (100%) rename mplot/{RhomboVisual.h => RhomboVisual.cppm} (100%) rename mplot/{RodVisual.h => RodVisual.cppm} (100%) rename mplot/{ScatterVisual.h => ScatterVisual.cppm} (100%) rename mplot/{SphereVisual.h => SphereVisual.cppm} (100%) rename mplot/{SphericalProjectionVisual.h => SphericalProjectionVisual.cppm} (100%) rename mplot/{TextFeatures.h => TextFeatures.cppm} (100%) rename mplot/{TextGeometry.h => TextGeometry.cppm} (100%) rename mplot/{TriaxesVisual.h => TriaxesVisual.cppm} (100%) rename mplot/{VectorVisual.h => VectorVisual.cppm} (100%) rename mplot/{VerticesVisual.h => VerticesVisual.cppm} (100%) rename mplot/{Visual.h => Visual.cppm} (100%) rename mplot/{VisualCommon.h => VisualCommon.cppm} (100%) rename mplot/{VisualDataModel.h => VisualDataModel.cppm} (100%) rename mplot/{VisualFace.h => VisualFace.cppm} (100%) rename mplot/{VisualFont.h => VisualFont.cppm} (100%) rename mplot/{VisualGlfw.h => VisualGlfw.cppm} (100%) rename mplot/{VisualModel.h => VisualModel.cppm} (100%) rename mplot/{VisualOwnable.h => VisualOwnable.cppm} (100%) rename mplot/{VisualResources.h => VisualResources.cppm} (100%) rename mplot/{VisualTextModel.h => VisualTextModel.cppm} (100%) rename mplot/{colour.h => colour.cppm} (100%) rename mplot/{colourmaps_cet.h => colourmaps_cet.cppm} (100%) rename mplot/{colourmaps_crameri.h => colourmaps_crameri.cppm} (100%) rename mplot/compoundray/{EyeVisual.h => EyeVisual.cppm} (100%) rename mplot/compoundray/{Ommatidium.h => Ommatidium.cppm} (100%) rename mplot/compoundray/{interop.h => interop.cppm} (100%) rename mplot/fps/{profiler.h => profiler.cppm} (100%) rename mplot/gl/{util_mx.h => util_mx.cppm} (100%) rename mplot/gl/{version.h => version.cppm} (100%) rename mplot/{graphing.h => graphing.cppm} (100%) rename mplot/{graphstyles.h => graphstyles.cppm} (100%) rename mplot/{loadpng.h => loadpng.cppm} (100%) rename mplot/{tools.h => tools.cppm} (100%) rename mplot/{unicode.h => unicode.cppm} (100%) rename mplot/{win_t.h => win_t.cppm} (100%) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 5b7f61ac..e7850579 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -25,35 +25,35 @@ set(SM_CORE_MODULES ) # Base modules for mathplot set(MPLOT_CORE_MODULES - ${PROJECT_SOURCE_DIR}/mplot/tools.h - ${PROJECT_SOURCE_DIR}/mplot/unicode.h - ${PROJECT_SOURCE_DIR}/mplot/loadpng.h - ${PROJECT_SOURCE_DIR}/mplot/gl/version.h - ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.h - ${PROJECT_SOURCE_DIR}/mplot/colour.h - ${PROJECT_SOURCE_DIR}/mplot/win_t.h - ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.h - ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.h - ${PROJECT_SOURCE_DIR}/mplot/Visual.h - ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFace.h - ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.h - ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.h - ${PROJECT_SOURCE_DIR}/mplot/VisualResources.h - ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.h - ${PROJECT_SOURCE_DIR}/mplot/VisualFont.h - ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.h - ${PROJECT_SOURCE_DIR}/mplot/VisualModel.h - ${PROJECT_SOURCE_DIR}/mplot/NavMesh.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.h - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.h - ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.h - ${PROJECT_SOURCE_DIR}/mplot/graphing.h - ${PROJECT_SOURCE_DIR}/mplot/graphstyles.h - ${PROJECT_SOURCE_DIR}/mplot/DatasetStyle.h - ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.h - ${PROJECT_SOURCE_DIR}/mplot/compoundray/Ommatidium.h + ${PROJECT_SOURCE_DIR}/mplot/tools.cppm + ${PROJECT_SOURCE_DIR}/mplot/unicode.cppm + ${PROJECT_SOURCE_DIR}/mplot/loadpng.cppm + ${PROJECT_SOURCE_DIR}/mplot/gl/version.cppm + ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.cppm + ${PROJECT_SOURCE_DIR}/mplot/colour.cppm + ${PROJECT_SOURCE_DIR}/mplot/win_t.cppm + ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.cppm + ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.cppm + ${PROJECT_SOURCE_DIR}/mplot/Visual.cppm + ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.cppm + ${PROJECT_SOURCE_DIR}/mplot/VisualFace.cppm + ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.cppm + ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.cppm + ${PROJECT_SOURCE_DIR}/mplot/VisualResources.cppm + ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.cppm + ${PROJECT_SOURCE_DIR}/mplot/VisualFont.cppm + ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.cppm + ${PROJECT_SOURCE_DIR}/mplot/VisualModel.cppm + ${PROJECT_SOURCE_DIR}/mplot/NavMesh.cppm + ${PROJECT_SOURCE_DIR}/mplot/ColourMap.cppm + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.cppm + ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.cppm + ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.cppm + ${PROJECT_SOURCE_DIR}/mplot/graphing.cppm + ${PROJECT_SOURCE_DIR}/mplot/graphstyles.cppm + ${PROJECT_SOURCE_DIR}/mplot/DatasetStyle.cppm + ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.cppm + ${PROJECT_SOURCE_DIR}/mplot/compoundray/Ommatidium.cppm ) # Maths used in individual VisualModels, but not the mathplot core @@ -82,18 +82,18 @@ set(SM_HEXGRID_MODULES ) set(MPLOT_VISUALMODEL_MODULES - ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h - ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h - ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h - ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.h - ${PROJECT_SOURCE_DIR}/mplot/SphereVisual.h - ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.h - ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.h - ${PROJECT_SOURCE_DIR}/mplot/compoundray/EyeVisual.h - ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.h - ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.h - ${PROJECT_SOURCE_DIR}/mplot/TriaxesVisual.h - ${PROJECT_SOURCE_DIR}/mplot/ScatterVisual.h + ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/GridVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/RodVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/SphereVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/compoundray/EyeVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/TriaxesVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/ScatterVisual.cppm ) # Each C++ module file has to be listed here (as they don't have a .cppm or .ixx file suffix) @@ -112,21 +112,21 @@ target_link_libraries(helloworld OpenGL::GL glfw Freetype::Freetype glad mplot_f add_executable(rod rod.cpp) target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h + FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/RodVisual.cppm ) target_link_libraries(rod OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) add_executable(rod_with_normals rod_with_normals.cpp) target_sources(rod_with_normals PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.h + FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/RodVisual.cppm ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.cppm ) target_link_libraries(rod_with_normals OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) add_executable(ellipsoid ellipsoid.cpp) target_sources(ellipsoid PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} - ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h - ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.h + ${PROJECT_SOURCE_DIR}/mplot/RodVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.cppm ) target_link_libraries(ellipsoid OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) @@ -134,9 +134,9 @@ if(NOT APPLE) add_executable(geodesic geodesic.cpp) target_sources(geodesic PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} - ${PROJECT_SOURCE_DIR}/mplot/RodVisual.h - ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.h - ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.h + ${PROJECT_SOURCE_DIR}/mplot/RodVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.cppm ) target_link_libraries(geodesic OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) endif() @@ -144,17 +144,17 @@ endif() add_executable(vectorvis vectorvis.cpp) target_sources(vectorvis PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} - ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.h + ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.cppm ) target_link_libraries(vectorvis OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) add_executable(cray_eye cray_eye.cpp) target_sources(cray_eye PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} - ${PROJECT_SOURCE_DIR}/mplot/SphereVisual.h - ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.h + ${PROJECT_SOURCE_DIR}/mplot/SphereVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.cppm ${PROJECT_SOURCE_DIR}/maths/sm/winder.cppm - ${PROJECT_SOURCE_DIR}/mplot/compoundray/EyeVisual.h + ${PROJECT_SOURCE_DIR}/mplot/compoundray/EyeVisual.cppm ) target_link_libraries(cray_eye OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) @@ -163,7 +163,7 @@ target_sources(graph1 PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/maths/sm/histo.cppm ${PROJECT_SOURCE_DIR}/maths/sm/grid.cppm - ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h + ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.cppm ) target_link_libraries(graph1 OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) @@ -172,7 +172,7 @@ add_executable(grid_simple grid_simple.cpp) target_sources(grid_simple PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/maths/sm/grid.cppm - ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h + ${PROJECT_SOURCE_DIR}/mplot/GridVisual.cppm ) target_link_libraries(grid_simple OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) @@ -181,8 +181,8 @@ if(NOT APPLE) add_executable(breadcrumbs breadcrumbs.cpp) target_sources(breadcrumbs PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} - ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.h - ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.h + ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.cppm ) target_link_libraries(breadcrumbs OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) endif() @@ -191,20 +191,20 @@ add_executable(showcase showcase.cpp) target_sources(showcase PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${SM_HEXGRID_MODULES} - ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.h - ${PROJECT_SOURCE_DIR}/mplot/TriaxesVisual.h - ${PROJECT_SOURCE_DIR}/mplot/ScatterVisual.h + ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/TriaxesVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/ScatterVisual.cppm ${PROJECT_SOURCE_DIR}/maths/sm/grid.cppm - ${PROJECT_SOURCE_DIR}/mplot/GridVisual.h + ${PROJECT_SOURCE_DIR}/mplot/GridVisual.cppm ${PROJECT_SOURCE_DIR}/maths/sm/histo.cppm - ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.h + ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.cppm ) target_link_libraries(showcase OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) add_executable(hexgrid hexgrid.cpp) target_sources(hexgrid PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${SM_HEXGRID_MODULES} - ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.h + ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.cppm ) target_link_libraries(hexgrid OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) diff --git a/mplot/ColourBarVisual.h b/mplot/ColourBarVisual.cppm similarity index 100% rename from mplot/ColourBarVisual.h rename to mplot/ColourBarVisual.cppm diff --git a/mplot/ColourMap.h b/mplot/ColourMap.cppm similarity index 100% rename from mplot/ColourMap.h rename to mplot/ColourMap.cppm diff --git a/mplot/ColourMap_Lists.h b/mplot/ColourMap_Lists.cppm similarity index 100% rename from mplot/ColourMap_Lists.h rename to mplot/ColourMap_Lists.cppm diff --git a/mplot/CoordArrows.h b/mplot/CoordArrows.cppm similarity index 100% rename from mplot/CoordArrows.h rename to mplot/CoordArrows.cppm diff --git a/mplot/CurvyTellyVisual.h b/mplot/CurvyTellyVisual.cppm similarity index 100% rename from mplot/CurvyTellyVisual.h rename to mplot/CurvyTellyVisual.cppm diff --git a/mplot/CyclicColourVisual.h b/mplot/CyclicColourVisual.cppm similarity index 100% rename from mplot/CyclicColourVisual.h rename to mplot/CyclicColourVisual.cppm diff --git a/mplot/DatasetStyle.h b/mplot/DatasetStyle.cppm similarity index 100% rename from mplot/DatasetStyle.h rename to mplot/DatasetStyle.cppm diff --git a/mplot/GeodesicVisual.h b/mplot/GeodesicVisual.cppm similarity index 100% rename from mplot/GeodesicVisual.h rename to mplot/GeodesicVisual.cppm diff --git a/mplot/GraphVisual.h b/mplot/GraphVisual.cppm similarity index 100% rename from mplot/GraphVisual.h rename to mplot/GraphVisual.cppm diff --git a/mplot/GratingVisual.h b/mplot/GratingVisual.cppm similarity index 100% rename from mplot/GratingVisual.h rename to mplot/GratingVisual.cppm diff --git a/mplot/GridVisual.h b/mplot/GridVisual.cppm similarity index 100% rename from mplot/GridVisual.h rename to mplot/GridVisual.cppm diff --git a/mplot/HSVWheelVisual.h b/mplot/HSVWheelVisual.cppm similarity index 100% rename from mplot/HSVWheelVisual.h rename to mplot/HSVWheelVisual.cppm diff --git a/mplot/HexGridVisual.h b/mplot/HexGridVisual.cppm similarity index 100% rename from mplot/HexGridVisual.h rename to mplot/HexGridVisual.cppm diff --git a/mplot/IcosaVisual.h b/mplot/IcosaVisual.cppm similarity index 100% rename from mplot/IcosaVisual.h rename to mplot/IcosaVisual.cppm diff --git a/mplot/InstancedScatterVisual.h b/mplot/InstancedScatterVisual.cppm similarity index 100% rename from mplot/InstancedScatterVisual.h rename to mplot/InstancedScatterVisual.cppm diff --git a/mplot/LengthscaleVisual.h b/mplot/LengthscaleVisual.cppm similarity index 100% rename from mplot/LengthscaleVisual.h rename to mplot/LengthscaleVisual.cppm diff --git a/mplot/NavMesh.h b/mplot/NavMesh.cppm similarity index 100% rename from mplot/NavMesh.h rename to mplot/NavMesh.cppm diff --git a/mplot/NormalsVisual.h b/mplot/NormalsVisual.cppm similarity index 100% rename from mplot/NormalsVisual.h rename to mplot/NormalsVisual.cppm diff --git a/mplot/PolarVisual.h b/mplot/PolarVisual.cppm similarity index 100% rename from mplot/PolarVisual.h rename to mplot/PolarVisual.cppm diff --git a/mplot/QuiverVisual.h b/mplot/QuiverVisual.cppm similarity index 100% rename from mplot/QuiverVisual.h rename to mplot/QuiverVisual.cppm diff --git a/mplot/RectangleVisual.h b/mplot/RectangleVisual.cppm similarity index 100% rename from mplot/RectangleVisual.h rename to mplot/RectangleVisual.cppm diff --git a/mplot/RhomboVisual.h b/mplot/RhomboVisual.cppm similarity index 100% rename from mplot/RhomboVisual.h rename to mplot/RhomboVisual.cppm diff --git a/mplot/RodVisual.h b/mplot/RodVisual.cppm similarity index 100% rename from mplot/RodVisual.h rename to mplot/RodVisual.cppm diff --git a/mplot/ScatterVisual.h b/mplot/ScatterVisual.cppm similarity index 100% rename from mplot/ScatterVisual.h rename to mplot/ScatterVisual.cppm diff --git a/mplot/SphereVisual.h b/mplot/SphereVisual.cppm similarity index 100% rename from mplot/SphereVisual.h rename to mplot/SphereVisual.cppm diff --git a/mplot/SphericalProjectionVisual.h b/mplot/SphericalProjectionVisual.cppm similarity index 100% rename from mplot/SphericalProjectionVisual.h rename to mplot/SphericalProjectionVisual.cppm diff --git a/mplot/TextFeatures.h b/mplot/TextFeatures.cppm similarity index 100% rename from mplot/TextFeatures.h rename to mplot/TextFeatures.cppm diff --git a/mplot/TextGeometry.h b/mplot/TextGeometry.cppm similarity index 100% rename from mplot/TextGeometry.h rename to mplot/TextGeometry.cppm diff --git a/mplot/TriaxesVisual.h b/mplot/TriaxesVisual.cppm similarity index 100% rename from mplot/TriaxesVisual.h rename to mplot/TriaxesVisual.cppm diff --git a/mplot/VectorVisual.h b/mplot/VectorVisual.cppm similarity index 100% rename from mplot/VectorVisual.h rename to mplot/VectorVisual.cppm diff --git a/mplot/VerticesVisual.h b/mplot/VerticesVisual.cppm similarity index 100% rename from mplot/VerticesVisual.h rename to mplot/VerticesVisual.cppm diff --git a/mplot/Visual.h b/mplot/Visual.cppm similarity index 100% rename from mplot/Visual.h rename to mplot/Visual.cppm diff --git a/mplot/VisualCommon.h b/mplot/VisualCommon.cppm similarity index 100% rename from mplot/VisualCommon.h rename to mplot/VisualCommon.cppm diff --git a/mplot/VisualDataModel.h b/mplot/VisualDataModel.cppm similarity index 100% rename from mplot/VisualDataModel.h rename to mplot/VisualDataModel.cppm diff --git a/mplot/VisualFace.h b/mplot/VisualFace.cppm similarity index 100% rename from mplot/VisualFace.h rename to mplot/VisualFace.cppm diff --git a/mplot/VisualFont.h b/mplot/VisualFont.cppm similarity index 100% rename from mplot/VisualFont.h rename to mplot/VisualFont.cppm diff --git a/mplot/VisualGlfw.h b/mplot/VisualGlfw.cppm similarity index 100% rename from mplot/VisualGlfw.h rename to mplot/VisualGlfw.cppm diff --git a/mplot/VisualModel.h b/mplot/VisualModel.cppm similarity index 100% rename from mplot/VisualModel.h rename to mplot/VisualModel.cppm diff --git a/mplot/VisualOwnable.h b/mplot/VisualOwnable.cppm similarity index 100% rename from mplot/VisualOwnable.h rename to mplot/VisualOwnable.cppm diff --git a/mplot/VisualResources.h b/mplot/VisualResources.cppm similarity index 100% rename from mplot/VisualResources.h rename to mplot/VisualResources.cppm diff --git a/mplot/VisualTextModel.h b/mplot/VisualTextModel.cppm similarity index 100% rename from mplot/VisualTextModel.h rename to mplot/VisualTextModel.cppm diff --git a/mplot/colour.h b/mplot/colour.cppm similarity index 100% rename from mplot/colour.h rename to mplot/colour.cppm diff --git a/mplot/colourmaps_cet.h b/mplot/colourmaps_cet.cppm similarity index 100% rename from mplot/colourmaps_cet.h rename to mplot/colourmaps_cet.cppm diff --git a/mplot/colourmaps_crameri.h b/mplot/colourmaps_crameri.cppm similarity index 100% rename from mplot/colourmaps_crameri.h rename to mplot/colourmaps_crameri.cppm diff --git a/mplot/compoundray/EyeVisual.h b/mplot/compoundray/EyeVisual.cppm similarity index 100% rename from mplot/compoundray/EyeVisual.h rename to mplot/compoundray/EyeVisual.cppm diff --git a/mplot/compoundray/Ommatidium.h b/mplot/compoundray/Ommatidium.cppm similarity index 100% rename from mplot/compoundray/Ommatidium.h rename to mplot/compoundray/Ommatidium.cppm diff --git a/mplot/compoundray/interop.h b/mplot/compoundray/interop.cppm similarity index 100% rename from mplot/compoundray/interop.h rename to mplot/compoundray/interop.cppm diff --git a/mplot/fps/profiler.h b/mplot/fps/profiler.cppm similarity index 100% rename from mplot/fps/profiler.h rename to mplot/fps/profiler.cppm diff --git a/mplot/gl/util_mx.h b/mplot/gl/util_mx.cppm similarity index 100% rename from mplot/gl/util_mx.h rename to mplot/gl/util_mx.cppm diff --git a/mplot/gl/version.h b/mplot/gl/version.cppm similarity index 100% rename from mplot/gl/version.h rename to mplot/gl/version.cppm diff --git a/mplot/graphing.h b/mplot/graphing.cppm similarity index 100% rename from mplot/graphing.h rename to mplot/graphing.cppm diff --git a/mplot/graphstyles.h b/mplot/graphstyles.cppm similarity index 100% rename from mplot/graphstyles.h rename to mplot/graphstyles.cppm diff --git a/mplot/loadpng.h b/mplot/loadpng.cppm similarity index 100% rename from mplot/loadpng.h rename to mplot/loadpng.cppm diff --git a/mplot/tools.h b/mplot/tools.cppm similarity index 100% rename from mplot/tools.h rename to mplot/tools.cppm diff --git a/mplot/unicode.h b/mplot/unicode.cppm similarity index 100% rename from mplot/unicode.h rename to mplot/unicode.cppm diff --git a/mplot/win_t.h b/mplot/win_t.cppm similarity index 100% rename from mplot/win_t.h rename to mplot/win_t.cppm From 85aa9f044ed90350d772367d6dd0f675a421ee1e Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 20 Mar 2026 16:54:29 +0000 Subject: [PATCH 093/106] Definitions in here have gone to sm::grid --- mplot/GridFeatures.h | 63 -------------------------------------------- 1 file changed, 63 deletions(-) delete mode 100644 mplot/GridFeatures.h diff --git a/mplot/GridFeatures.h b/mplot/GridFeatures.h deleted file mode 100644 index fc21aa65..00000000 --- a/mplot/GridFeatures.h +++ /dev/null @@ -1,63 +0,0 @@ -/*! - * \file GridFeatures.h - * - * This contains some definitions that are used by CartGrid.h, Grid.h and Gridct.h, all of which - * define Cartesian grids. - * - * \author Seb James - * \date Feb 2024 - */ -#pragma once - -namespace mplot -{ - //! The shape of the cartesian grid. Only used by CartGrid.h as Grid.h only specifies rectangular grids. - enum class GridDomainShape - { - Rectangle, - Boundary // The shape of the arbitrary boundary set with CartGrid::setBoundary - }; - - //! The wrapping employed for the Cartesian grid. - enum class GridDomainWrap - { - None, // No wrapping - Horizontal, // The eastern neighbour of the most eastern element is the most western element on that row - Vertical, // The northern neighbour of the most northern element is the most southern element on that col - Both - }; - - /*! - * What's the ordering of a rectangular grid? - * - * An example grid of width 4 and height 2 should illustrate: - * - * bottomleft_to_topright: - * - * 4 5 6 7 - * 0 1 2 3 - * - * topleft_to_bottomright: - * - * 0 1 2 3 - * 4 5 6 7 - * - * bottomleft_to_topright_colmaj: - * - * 1 3 5 7 - * 0 2 4 6 - * - * topleft_to_bottomright_colmaj: - * - * 0 2 4 6 - * 1 3 5 7 - */ - enum class GridOrder - { - bottomleft_to_topright, - topleft_to_bottomright, - bottomleft_to_topright_colmaj, - topleft_to_bottomright_colmaj - }; - -} // namespace mplot From f0f8494999d31cf94da8a6af18337d24c14b6580 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 20 Mar 2026 16:59:30 +0000 Subject: [PATCH 094/106] Typo --- mplot/VisualFaceAsm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mplot/VisualFaceAsm.h b/mplot/VisualFaceAsm.h index c007ef90..953cde11 100644 --- a/mplot/VisualFaceAsm.h +++ b/mplot/VisualFaceAsm.h @@ -1,4 +1,4 @@ -// See also VisualFaceAsm.c +// See also VisualFaceAsm.cpp // These external pointers are set up by the inline assembly above #ifndef _MSC_VER From d3c5e11a5f15d894b5702463f380f098f4d33c52 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 20 Mar 2026 17:06:26 +0000 Subject: [PATCH 095/106] Refactor headers to .hpp to show they're not going to be modules --- mplot/CMakeLists.txt | 2 +- mplot/VisualFace.cppm | 6 +----- mplot/VisualFaceAsm.cpp | 2 +- mplot/{VisualFaceAsm.h => VisualFaceAsm.hpp} | 0 4 files changed, 3 insertions(+), 7 deletions(-) rename mplot/{VisualFaceAsm.h => VisualFaceAsm.hpp} (100%) diff --git a/mplot/CMakeLists.txt b/mplot/CMakeLists.txt index 76800fa5..bcffb6ab 100644 --- a/mplot/CMakeLists.txt +++ b/mplot/CMakeLists.txt @@ -32,7 +32,7 @@ install( VisualDefaultShaders.h VisualFaceBase.h - VisualFace.h + VisualFaceAsm.hpp VisualResourcesBase.h VisualResources.h diff --git a/mplot/VisualFace.cppm b/mplot/VisualFace.cppm index fe43db11..580a72a4 100644 --- a/mplot/VisualFace.cppm +++ b/mplot/VisualFace.cppm @@ -26,11 +26,7 @@ module; #include #include -#include - -/* - * Module starts here - */ +#include export module mplot.visualface; diff --git a/mplot/VisualFaceAsm.cpp b/mplot/VisualFaceAsm.cpp index 80ccc77e..4e36658d 100644 --- a/mplot/VisualFaceAsm.cpp +++ b/mplot/VisualFaceAsm.cpp @@ -100,7 +100,7 @@ INCBIN(dvsansbi, "./fonts/dejavu/DejaVuSans-BoldOblique.ttf"); # error "Inline assembly code for including truetype fonts in the binary only work on Linux/MacOS (and then, probably only on Intel compatible compilers. Sorry about that!" #endif -#include +#include // Dummy function int meaningless::function() { return 42; } diff --git a/mplot/VisualFaceAsm.h b/mplot/VisualFaceAsm.hpp similarity index 100% rename from mplot/VisualFaceAsm.h rename to mplot/VisualFaceAsm.hpp From 8afdd789019482ed4504bf697baf2002f535a2fb Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 20 Mar 2026 22:07:37 +0000 Subject: [PATCH 096/106] A new scheme to set up the modules variables --- CMakeLists.txt | 128 ++++----------------------------- cmake/module_definitions.cmake | 112 +++++++++++++++++++++++++++++ examples/CMakeLists.txt | 125 ++++---------------------------- maths | 2 +- 4 files changed, 141 insertions(+), 226 deletions(-) create mode 100644 cmake/module_definitions.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 07f08b5a..afe3e896 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,9 @@ message(STATUS " (This can be changed with `cmake -DCMAKE_INSTALL_PREFIX=/some/ set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) +# Add our cmake directory and our submodule maths's cmake dir to cmake modules path +set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) + # For future import std; support # set(CMAKE_CXX_EXTENSIONS ON) # Tell CMake that we explicitly want `import std`. This will initialize the @@ -186,121 +189,16 @@ endif() # else we have it in a directory included by default in the path # # sebsjames/maths module groups # -set(SM_CONSTEXPR_MATH_MODULES - ${PROJECT_SOURCE_DIR}/sm/mathconst.cppm - ${PROJECT_SOURCE_DIR}/sm/constexpr_math.cppm -) -set(SM_POLYSOLVE_MODULES - ${SM_CONSTEXPR_MATH_MODULES} - ${PROJECT_SOURCE_DIR}/sm/polysolve.cppm -) -set(SM_BESSEL_I0_MODULES - ${SM_POLYSOLVE_MODULES} - ${PROJECT_SOURCE_DIR}/sm/bessel_i0.cppm -) -set(SM_RANDOM_MODULES - ${SM_BESSEL_I0_MODULES} - ${PROJECT_SOURCE_DIR}/sm/random -) -set(SM_RANGE_MODULES - ${SM_CONSTEXPR_MATH_MODULES} - ${PROJECT_SOURCE_DIR}/sm/trait_tests.cppm - ${PROJECT_SOURCE_DIR}/sm/range.cppm -) -set(SM_VEC_MODULES - ${SM_RANGE_MODULES} - ${SM_RANDOM_MODULES} - ${PROJECT_SOURCE_DIR}/sm/vec.cppm -) -set(SM_VVEC_MODULES - ${SM_RANGE_MODULES} - ${SM_RANDOM_MODULES} - ${PROJECT_SOURCE_DIR}/sm/vvec.cppm -) -set(SM_SCALE_MODULES - ${SM_VVEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/scale.cppm -) -set(SM_UTIL_MODULES - ${PROJECT_SOURCE_DIR}/sm/trait_tests.cppm - ${PROJECT_SOURCE_DIR}/sm/util.cppm -) -set(SM_HDFDATA_MODULES - ${SM_VEC_MODULES} - ${SM_VVEC_MODULES} - ${SM_UTIL_MODULES} - ${PROJECT_SOURCE_DIR}/sm/hdfdata.cppm -) -set(SM_QUATERNION_MODULES - ${SM_VEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/quaternion.cppm -) -set(SM_MAT_MODULES - ${SM_QUATERNION_MODULES} - ${PROJECT_SOURCE_DIR}/sm/mat.cppm -) -set(SM_BEZCOORD_MODULES - ${SM_VEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/bezcoord.cppm -) -set(SM_HEX_MODULES - ${SM_BEZCOORD_MODULES} - ${PROJECT_SOURCE_DIR}/sm/hex.cppm -) -set(SM_WINDER_MODULES - ${SM_VEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/winder.cppm -) -set(SM_BOOTSTRAP_MODULES - ${SM_VEC_MODULES} - ${SM_VVEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/bootstrap.cppm -) -set(SM_GRID_MODULES - ${SM_VEC_MODULES} - ${SM_VVEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/grid.cppm -) -set(SM_ALGO_MODULES - ${SM_VEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/algo.cppm -) -set(SM_NM_SIMPLEX_MODULES - ${SM_ALGO_MODULES} - ${SM_VVEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/nm_simplex.cppm -) -set(SM_HISTO_MODULES - ${SM_VEC_MODULES} - ${SM_VVEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/histo.cppm -) -set(SM_BOXFILTER_MODULES - ${SM_VEC_MODULES} - ${SM_VVEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/boxfilter.cppm -) -set(SM_GEOMETRY_MODULES - ${SM_ALGO_MODULES} - ${SM_VVEC_MODULES} - ${PROJECT_SOURCE_DIR}/sm/geometry.cppm -) -set(SM_BEZCURVE_MODULES - ${SM_BEZCOORD_MODULES} - ${SM_MAT_MODULES} - ${SM_NM_SIMPLEX_MODULES} - ${PROJECT_SOURCE_DIR}/sm/binomial.cppm - ${PROJECT_SOURCE_DIR}/sm/bezcurve.cppm -) -set(SM_BEZCURVEPATH_MODULES - ${SM_BEZCURVE_MODULES} - ${PROJECT_SOURCE_DIR}/sm/bezcurvepath.cppm -) -set(SM_HEXGRID_MODULES - ${SM_BEZCURVEPATH_MODULES} - ${SM_HEX_MODULES} - ${PROJECT_SOURCE_DIR}/sm/hexgrid.cppm -) + +# Include maths module defs +include(${PROJECT_SOURCE_DIR}/maths/cmake/module_definitions.cmake) +setup_module_variables_for_maths (${PROJECT_SOURCE_DIR}/maths) + +# Include our own module defs +include(${PROJECT_SOURCE_DIR}/cmake/module_definitions.cmake) +setup_module_variables_for_mathplot_maths (${PROJECT_SOURCE_DIR}/maths) +setup_module_variables_for_mathplot (${PROJECT_SOURCE_DIR}) + # All the mathplot headers are here add_subdirectory(mplot) diff --git a/cmake/module_definitions.cmake b/cmake/module_definitions.cmake new file mode 100644 index 00000000..f9033486 --- /dev/null +++ b/cmake/module_definitions.cmake @@ -0,0 +1,112 @@ +# +# Define variables of module groups for use by the sebsjames/mathplot +# build process itself, and by client projects. +# + +# Sets up variables the define the sebsjames/maths modules used +# building mathplot. Pass in the path to the sebsjames/maths root. +macro(setup_module_variables_for_mathplot_maths base_directory) + + # These are set assuming a submoduled maths. + set(MPLOT_MATHS_CORE_MODULES + ${base_directory}/sm/mathconst.cppm + ${base_directory}/sm/constexpr_math.cppm + ${base_directory}/sm/range.cppm + ${base_directory}/sm/polysolve.cppm + ${base_directory}/sm/bessel_i0.cppm + ${base_directory}/sm/random.cppm + ${base_directory}/sm/vec.cppm + ${base_directory}/sm/quaternion.cppm + ${base_directory}/sm/mat.cppm + ${base_directory}/sm/trait_tests.cppm + ${base_directory}/sm/util.cppm + ${base_directory}/sm/base64.cppm + ${base_directory}/sm/crc32.cppm + ${base_directory}/sm/flags.cppm + ${base_directory}/sm/algo.cppm + ${base_directory}/sm/geometry.cppm + ${base_directory}/sm/geometry_polyhedra.cppm + ${base_directory}/sm/vvec.cppm + ${base_directory}/sm/scale.cppm + ${base_directory}/sm/centroid.cppm + ) + + # The modules required for hexgrids + set(MPLOT_MATHS_HEXGRID_MODULES + ${base_directory}/sm/nm_simplex.cppm + ${base_directory}/sm/binomial.cppm + ${base_directory}/sm/bezcoord.cppm + ${base_directory}/sm/bezcurve.cppm + ${base_directory}/sm/bezcurvepath.cppm + ${base_directory}/sm/hex.cppm + ${base_directory}/sm/hexgrid.cppm + ) + + # Maths used in individual VisualModels, but not the mathplot core + set(MPLOT_MATHS_VISUALMODEL_MODULES + ${base_directory}/sm/winder.cppm + ${base_directory}/sm/histo.cppm + ${base_directory}/sm/grid.cppm + ${base_directory}/sm/nm_simplex.cppm + ${base_directory}/sm/bezcoord.cppm + ${base_directory}/sm/binomial.cppm + ${base_directory}/sm/bezcurve.cppm + ${base_directory}/sm/bezcurvepath.cppm + ${base_directory}/sm/hex.cppm + ${base_directory}/sm/hexgrid.cppm + ) +endmacro() + +macro(setup_module_variables_for_mathplot base_directory) + + # Base modules for mathplot. With these (and + # MPLOT_MATHS_CORE_MODULES) you can build helloworld + set(MPLOT_CORE_MODULES + ${base_directory}/mplot/tools.cppm + ${base_directory}/mplot/unicode.cppm + ${base_directory}/mplot/loadpng.cppm + ${base_directory}/mplot/gl/version.cppm + ${base_directory}/mplot/gl/util_mx.cppm + ${base_directory}/mplot/colour.cppm + ${base_directory}/mplot/win_t.cppm + ${base_directory}/mplot/CoordArrows.cppm + ${base_directory}/mplot/VisualOwnable.cppm + ${base_directory}/mplot/Visual.cppm + ${base_directory}/mplot/VisualGlfw.cppm + ${base_directory}/mplot/VisualFace.cppm + ${base_directory}/mplot/TextFeatures.cppm + ${base_directory}/mplot/TextGeometry.cppm + ${base_directory}/mplot/VisualResources.cppm + ${base_directory}/mplot/VisualCommon.cppm + ${base_directory}/mplot/VisualFont.cppm + ${base_directory}/mplot/VisualTextModel.cppm + ${base_directory}/mplot/VisualModel.cppm + ${base_directory}/mplot/NavMesh.cppm + ${base_directory}/mplot/ColourMap.cppm + ${base_directory}/mplot/colourmaps_cet.cppm + ${base_directory}/mplot/colourmaps_crameri.cppm + ${base_directory}/mplot/ColourMap_Lists.cppm + ${base_directory}/mplot/graphing.cppm + ${base_directory}/mplot/graphstyles.cppm + ${base_directory}/mplot/DatasetStyle.cppm + ${base_directory}/mplot/VisualDataModel.cppm + ${base_directory}/mplot/compoundray/Ommatidium.cppm + ) + + # All the VisualModel modules + set(MPLOT_VISUALMODEL_MODULES + ${base_directory}/mplot/GraphVisual.cppm + ${base_directory}/mplot/GridVisual.cppm + ${base_directory}/mplot/RodVisual.cppm + ${base_directory}/mplot/VectorVisual.cppm + ${base_directory}/mplot/SphereVisual.cppm + ${base_directory}/mplot/NormalsVisual.cppm + ${base_directory}/mplot/GeodesicVisual.cppm + ${base_directory}/mplot/compoundray/EyeVisual.cppm + ${base_directory}/mplot/InstancedScatterVisual.cppm + ${base_directory}/mplot/HexGridVisual.cppm + ${base_directory}/mplot/TriaxesVisual.cppm + ${base_directory}/mplot/ScatterVisual.cppm + ) + +endmacro() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index e7850579..e1519c22 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,130 +1,35 @@ # All #includes in test programs have to be #include include_directories(BEFORE ${PROJECT_SOURCE_DIR}) -set(SM_CORE_MODULES - ${PROJECT_SOURCE_DIR}/maths/sm/mathconst.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/constexpr_math.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/range.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/polysolve.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/bessel_i0.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/random.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/vec.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/quaternion.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/mat.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/trait_tests.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/util.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/base64.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/crc32.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/flags.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/algo.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/geometry.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/geometry_polyhedra.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/vvec.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/scale.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/centroid.cppm -) -# Base modules for mathplot -set(MPLOT_CORE_MODULES - ${PROJECT_SOURCE_DIR}/mplot/tools.cppm - ${PROJECT_SOURCE_DIR}/mplot/unicode.cppm - ${PROJECT_SOURCE_DIR}/mplot/loadpng.cppm - ${PROJECT_SOURCE_DIR}/mplot/gl/version.cppm - ${PROJECT_SOURCE_DIR}/mplot/gl/util_mx.cppm - ${PROJECT_SOURCE_DIR}/mplot/colour.cppm - ${PROJECT_SOURCE_DIR}/mplot/win_t.cppm - ${PROJECT_SOURCE_DIR}/mplot/CoordArrows.cppm - ${PROJECT_SOURCE_DIR}/mplot/VisualOwnable.cppm - ${PROJECT_SOURCE_DIR}/mplot/Visual.cppm - ${PROJECT_SOURCE_DIR}/mplot/VisualGlfw.cppm - ${PROJECT_SOURCE_DIR}/mplot/VisualFace.cppm - ${PROJECT_SOURCE_DIR}/mplot/TextFeatures.cppm - ${PROJECT_SOURCE_DIR}/mplot/TextGeometry.cppm - ${PROJECT_SOURCE_DIR}/mplot/VisualResources.cppm - ${PROJECT_SOURCE_DIR}/mplot/VisualCommon.cppm - ${PROJECT_SOURCE_DIR}/mplot/VisualFont.cppm - ${PROJECT_SOURCE_DIR}/mplot/VisualTextModel.cppm - ${PROJECT_SOURCE_DIR}/mplot/VisualModel.cppm - ${PROJECT_SOURCE_DIR}/mplot/NavMesh.cppm - ${PROJECT_SOURCE_DIR}/mplot/ColourMap.cppm - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_cet.cppm - ${PROJECT_SOURCE_DIR}/mplot/colourmaps_crameri.cppm - ${PROJECT_SOURCE_DIR}/mplot/ColourMap_Lists.cppm - ${PROJECT_SOURCE_DIR}/mplot/graphing.cppm - ${PROJECT_SOURCE_DIR}/mplot/graphstyles.cppm - ${PROJECT_SOURCE_DIR}/mplot/DatasetStyle.cppm - ${PROJECT_SOURCE_DIR}/mplot/VisualDataModel.cppm - ${PROJECT_SOURCE_DIR}/mplot/compoundray/Ommatidium.cppm -) - -# Maths used in individual VisualModels, but not the mathplot core -set(SM_VISUALMODEL_MODULES - ${PROJECT_SOURCE_DIR}/maths/sm/winder.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/histo.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/grid.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/binomial.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/bezcurve.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/bezcurvepath.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/hex.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/hexgrid.cppm -) - -# The modules required for hexgrids -set(SM_HEXGRID_MODULES - ${PROJECT_SOURCE_DIR}/maths/sm/nm_simplex.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/binomial.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/bezcoord.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/bezcurve.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/bezcurvepath.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/hex.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/hexgrid.cppm -) - -set(MPLOT_VISUALMODEL_MODULES - ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.cppm - ${PROJECT_SOURCE_DIR}/mplot/GridVisual.cppm - ${PROJECT_SOURCE_DIR}/mplot/RodVisual.cppm - ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.cppm - ${PROJECT_SOURCE_DIR}/mplot/SphereVisual.cppm - ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.cppm - ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.cppm - ${PROJECT_SOURCE_DIR}/mplot/compoundray/EyeVisual.cppm - ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.cppm - ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.cppm - ${PROJECT_SOURCE_DIR}/mplot/TriaxesVisual.cppm - ${PROJECT_SOURCE_DIR}/mplot/ScatterVisual.cppm -) - # Each C++ module file has to be listed here (as they don't have a .cppm or .ixx file suffix) set_source_files_properties ( - ${SM_CORE_MODULES} + ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} - ${SM_VISUALMODEL_MODULES} + ${MPLOT_MATHS_VISUALMODEL_MODULES} ${MPLOT_VISUALMODEL_MODULES} PROPERTIES LANGUAGE CXX ) add_executable(helloworld helloworld.cpp) target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES ${MPLOT_CORE_MODULES} ${SM_CORE_MODULES}) + FILES ${MPLOT_CORE_MODULES} ${MPLOT_MATHS_CORE_MODULES}) target_link_libraries(helloworld OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) add_executable(rod rod.cpp) target_sources(rod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/RodVisual.cppm + FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/RodVisual.cppm ) target_link_libraries(rod OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) add_executable(rod_with_normals rod_with_normals.cpp) target_sources(rod_with_normals PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/RodVisual.cppm ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.cppm + FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/RodVisual.cppm ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.cppm ) target_link_libraries(rod_with_normals OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) add_executable(ellipsoid ellipsoid.cpp) target_sources(ellipsoid PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} + FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/RodVisual.cppm ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.cppm ) @@ -133,7 +38,7 @@ target_link_libraries(ellipsoid OpenGL::GL glfw Freetype::Freetype glad mplot_fo if(NOT APPLE) add_executable(geodesic geodesic.cpp) target_sources(geodesic PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} + FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/RodVisual.cppm ${PROJECT_SOURCE_DIR}/mplot/NormalsVisual.cppm ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.cppm @@ -143,14 +48,14 @@ endif() add_executable(vectorvis vectorvis.cpp) target_sources(vectorvis PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} + FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.cppm ) target_link_libraries(vectorvis OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) add_executable(cray_eye cray_eye.cpp) target_sources(cray_eye PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} + FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/SphereVisual.cppm ${PROJECT_SOURCE_DIR}/mplot/VectorVisual.cppm ${PROJECT_SOURCE_DIR}/maths/sm/winder.cppm @@ -160,7 +65,7 @@ target_link_libraries(cray_eye OpenGL::GL glfw Freetype::Freetype glad mplot_fon add_executable(graph1 graph1.cpp) target_sources(graph1 PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} + FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/maths/sm/histo.cppm ${PROJECT_SOURCE_DIR}/maths/sm/grid.cppm ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.cppm @@ -170,7 +75,7 @@ target_link_libraries(graph1 OpenGL::GL glfw Freetype::Freetype glad mplot_fontd # sm::grid visualization example add_executable(grid_simple grid_simple.cpp) target_sources(grid_simple PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} + FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/maths/sm/grid.cppm ${PROJECT_SOURCE_DIR}/mplot/GridVisual.cppm ) @@ -180,7 +85,7 @@ if(NOT APPLE) # Instancing also not available on Apple (limited to OpenGL 4.1) add_executable(breadcrumbs breadcrumbs.cpp) target_sources(breadcrumbs PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} + FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.cppm ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.cppm ) @@ -189,8 +94,8 @@ endif() add_executable(showcase showcase.cpp) target_sources(showcase PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} - ${SM_HEXGRID_MODULES} + FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} + ${MPLOT_MATHS_HEXGRID_MODULES} ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.cppm ${PROJECT_SOURCE_DIR}/mplot/TriaxesVisual.cppm ${PROJECT_SOURCE_DIR}/mplot/ScatterVisual.cppm @@ -203,7 +108,7 @@ target_sources(showcase PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_D add_executable(hexgrid hexgrid.cpp) target_sources(hexgrid PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES ${SM_CORE_MODULES} ${MPLOT_CORE_MODULES} ${SM_HEXGRID_MODULES} + FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} ${MPLOT_MATHS_HEXGRID_MODULES} ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.cppm ) target_link_libraries(hexgrid OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) diff --git a/maths b/maths index 2c10dddc..340ccab0 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit 2c10dddc6844b12259f0df5669e770d19ba7b543 +Subproject commit 340ccab0d67fe118995448e8baa0414bd4af7afe From 2329acd4e79915ab7fae404bbe1d5f7ab9bc2fd1 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 20 Mar 2026 22:21:25 +0000 Subject: [PATCH 097/106] Can now have extra examples --- CMakeLists.txt | 6 ++++-- examples/CMakeLists.txt | 32 +++++++++++++++++++------------- examples/visual.cpp | 12 ++++++------ 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index afe3e896..8efaca19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -227,10 +227,12 @@ endif(BUILD_UTILS) add_subdirectory(fonts) # Example code (you can also see tests/ for examples) +option(BUILD_EXAMPLES_EXTRA "Build extra examples" OFF) option(BUILD_EXAMPLES "Build examples" ON) -if(BUILD_EXAMPLES) +if(BUILD_EXAMPLES OR BUILD_EXAMPLES_EXTRA) add_subdirectory(examples) -endif(BUILD_EXAMPLES) +endif(BUILD_EXAMPLES OR BUILD_EXAMPLES_EXTRA) + # Additional examples (requires BUILD_EXAMPLES ON) option(BUILD_DOC_SCREENSHOTS "Build documentation screenshot examples" OFF) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index e1519c22..3b9d31bf 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,14 +1,14 @@ # All #includes in test programs have to be #include include_directories(BEFORE ${PROJECT_SOURCE_DIR}) -# Each C++ module file has to be listed here (as they don't have a .cppm or .ixx file suffix) -set_source_files_properties ( - ${MPLOT_MATHS_CORE_MODULES} - ${MPLOT_CORE_MODULES} - ${MPLOT_MATHS_VISUALMODEL_MODULES} - ${MPLOT_VISUALMODEL_MODULES} - PROPERTIES LANGUAGE CXX -) +# Each C++ module file has to be listed here (as they may not have a .cppm file suffix) +#set_source_files_properties ( +# ${MPLOT_MATHS_CORE_MODULES} +# ${MPLOT_MATHS_VISUALMODEL_MODULES} +# ${MPLOT_CORE_MODULES} +# ${MPLOT_VISUALMODEL_MODULES} +# PROPERTIES LANGUAGE CXX +#) add_executable(helloworld helloworld.cpp) target_sources(helloworld PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} @@ -96,12 +96,12 @@ add_executable(showcase showcase.cpp) target_sources(showcase PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} ${MPLOT_MATHS_HEXGRID_MODULES} + ${PROJECT_SOURCE_DIR}/maths/sm/grid.cppm + ${PROJECT_SOURCE_DIR}/maths/sm/histo.cppm ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.cppm ${PROJECT_SOURCE_DIR}/mplot/TriaxesVisual.cppm ${PROJECT_SOURCE_DIR}/mplot/ScatterVisual.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/grid.cppm ${PROJECT_SOURCE_DIR}/mplot/GridVisual.cppm - ${PROJECT_SOURCE_DIR}/maths/sm/histo.cppm ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.cppm ) target_link_libraries(showcase OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) @@ -113,11 +113,17 @@ target_sources(showcase PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_D ) target_link_libraries(hexgrid OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) -if(0) # During development - +if(BUILD_EXAMPLES_EXTRA) # Basic mplot::Visual class example add_executable(visual visual.cpp) - target_link_libraries(visual OpenGL::GL glfw Freetype::Freetype) + target_sources(visual PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} ${MPLOT_MATHS_HEXGRID_MODULES} + ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.cppm + ) + target_link_libraries(visual OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) +endif() + +if (0) # During development add_executable(convolve_rect convolve_rect.cpp) target_link_libraries(convolve_rect OpenGL::GL glfw Freetype::Freetype) diff --git a/examples/visual.cpp b/examples/visual.cpp index 7cfff73f..26c9047f 100644 --- a/examples/visual.cpp +++ b/examples/visual.cpp @@ -2,16 +2,16 @@ * An example mplot::Visual scene, containing a HexGrid. */ +#include #include #include #include -#include -#include +import sm.vec; +import sm.hexgrid; -#include -#include -#include +import mplot.visual; +import mplot.hexgridvisual; int main() { @@ -55,7 +55,7 @@ int main() // Add a HexGridVisual to display the hexgrid within the mplot::Visual scene sm::vec offset = { 0.0, -0.05, 0.0 }; auto hgv = std::make_unique>(&hg, offset); - v.bindmodel (hgv); + hgv->set_parent (v.get_id()); hgv->setScalarData (&data); hgv->finalize(); v.addVisualModel (hgv); From d2acadde37332ad4032f6efcb3dfed4e3c5a2fe9 Mon Sep 17 00:00:00 2001 From: Seb James Date: Mon, 23 Mar 2026 16:08:37 +0000 Subject: [PATCH 098/106] Updates to config (making it a module) don't affect the current build --- maths | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths b/maths index 340ccab0..29062643 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit 340ccab0d67fe118995448e8baa0414bd4af7afe +Subproject commit 2906264315d33878625a415f840c0437b623339e From 48eed8347bb0608a787e4d1c77380f6e01839aa6 Mon Sep 17 00:00:00 2001 From: Seb James Date: Mon, 23 Mar 2026 17:01:04 +0000 Subject: [PATCH 099/106] maths is all modules now --- maths | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maths b/maths index 29062643..9cd8a796 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit 2906264315d33878625a415f840c0437b623339e +Subproject commit 9cd8a79634d8e9c1f78d1a1470585d334a817663 From 1715a48bafc857e2d53a2f42ba9afbfb06caef1b Mon Sep 17 00:00:00 2001 From: Seb James Date: Tue, 24 Mar 2026 11:16:48 +0000 Subject: [PATCH 100/106] Enables modular build of model_crawler example --- examples/CMakeLists.txt | 22 +++++++++++++++------- examples/model_crawler.cpp | 30 ++++++++++++++++-------------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 3b9d31bf..cd425e91 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -104,14 +104,22 @@ target_sources(showcase PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_D ${PROJECT_SOURCE_DIR}/mplot/GridVisual.cppm ${PROJECT_SOURCE_DIR}/mplot/GraphVisual.cppm ) - target_link_libraries(showcase OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) +target_link_libraries(showcase OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) - add_executable(hexgrid hexgrid.cpp) - target_sources(hexgrid PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} - FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} ${MPLOT_MATHS_HEXGRID_MODULES} - ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.cppm - ) - target_link_libraries(hexgrid OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) +add_executable(hexgrid hexgrid.cpp) +target_sources(hexgrid PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} ${MPLOT_MATHS_HEXGRID_MODULES} + ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.cppm +) +target_link_libraries(hexgrid OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) + +add_executable(model_crawler model_crawler.cpp) +target_sources(model_crawler PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} ${MPLOT_MATHS_HEXGRID_MODULES} + ${PROJECT_SOURCE_DIR}/mplot/InstancedScatterVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/GeodesicVisual.cppm +) +target_link_libraries(model_crawler OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) if(BUILD_EXAMPLES_EXTRA) # Basic mplot::Visual class example diff --git a/examples/model_crawler.cpp b/examples/model_crawler.cpp index 0037a8bc..85300776 100644 --- a/examples/model_crawler.cpp +++ b/examples/model_crawler.cpp @@ -10,20 +10,22 @@ #include #include #include +#include -#include -#include -#include -#include +import sm.random; +import sm.vec; +import sm.mat; +import sm.vvec; -#include -constexpr int32_t glver = mplot::gl::version_4_3; +import mplot.gl.version; -#include -#include -#include -#include -#include +import mplot.visual; +import mplot.colourmap; +import mplot.coordarrows; +import mplot.instancedscattervisual; +import mplot.geodesicvisual; + +constexpr std::int32_t glver = mplot::gl::version_4_3; int main (int argc, char** argv) { @@ -51,7 +53,7 @@ int main (int argc, char** argv) // A CoordArrows is our "crawling" agent auto ca = std::make_unique> (arrows_loc); - v.bindmodel (ca); + ca->set_parent (v.get_id()); ca->finalize(); [[maybe_unused]] auto cap = v.addVisualModel (ca); @@ -61,7 +63,7 @@ int main (int argc, char** argv) sm::vvec> sv_points = {}; sm::vvec sv_data = {}; auto isv = std::make_unique> (sphere_loc); - v.bindmodel (isv); + isv->set_parent (v.get_id()); isv->max_instances = max_bc; isv->radiusFixed = 0.01f; isv->finalize(); @@ -71,7 +73,7 @@ int main (int argc, char** argv) mplot::ColourMap cm (mplot::ColourMapType::Jet); auto cl = cm.convert (0.5f); auto gv = std::make_unique> (sphere_loc, radius); - v.bindmodel (gv); + gv->set_parent (v.get_id()); gv->iterations = geo_itrns; std::string lbl = "GeodesicVisual with computed NavMesh"; gv->addLabel (lbl, {0, -(radius + 0.1f), 0}, mplot::TextFeatures (0.06f)); From 97a30a4d9e6cc122fb222c508e6d118a2d1e12c1 Mon Sep 17 00:00:00 2001 From: Seb James Date: Wed, 25 Mar 2026 22:26:46 +0000 Subject: [PATCH 101/106] Adds the rosenbrock example --- examples/CMakeLists.txt | 14 +++++--- examples/rosenbrock.cpp | 34 +++++++++++-------- maths | 2 +- .../{TriFrameVisual.h => TriFrameVisual.cppm} | 31 +++++++++-------- 4 files changed, 48 insertions(+), 33 deletions(-) rename mplot/{TriFrameVisual.h => TriFrameVisual.cppm} (76%) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index cd425e91..c1f2b32e 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -129,6 +129,16 @@ if(BUILD_EXAMPLES_EXTRA) ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.cppm ) target_link_libraries(visual OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) + + add_executable(rosenbrock rosenbrock.cpp) + target_sources(rosenbrock PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR} + FILES ${MPLOT_MATHS_CORE_MODULES} ${MPLOT_CORE_MODULES} ${MPLOT_MATHS_HEXGRID_MODULES} + ${PROJECT_SOURCE_DIR}/mplot/HexGridVisual.cppm + ${PROJECT_SOURCE_DIR}/mplot/TriFrameVisual.cppm + ) + target_compile_definitions(rosenbrock PUBLIC FLT=float) + target_link_libraries(rosenbrock OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) + endif() if (0) # During development @@ -197,10 +207,6 @@ if (0) # During development add_executable(scatter_hex_mercator scatter_hex_mercator.cpp) target_link_libraries(scatter_hex_mercator OpenGL::GL glfw Freetype::Freetype) - add_executable(rosenbrock rosenbrock.cpp) - target_compile_definitions(rosenbrock PUBLIC FLT=float) - target_link_libraries(rosenbrock OpenGL::GL glfw Freetype::Freetype) - add_executable(rosenbrock_asa rosenbrock_asa.cpp) target_compile_definitions(rosenbrock_asa PUBLIC FLT=float VISUALISE) target_link_libraries(rosenbrock_asa OpenGL::GL glfw Freetype::Freetype) diff --git a/examples/rosenbrock.cpp b/examples/rosenbrock.cpp index ac9f7e65..6243218e 100644 --- a/examples/rosenbrock.cpp +++ b/examples/rosenbrock.cpp @@ -2,17 +2,23 @@ * Test Nelder Mead Simplex algorithm on the Rosenbrock banana function. */ -#include -#include -#include -#include -#include - -#include -#include -#include +#include #include +#include +#include #include +#include +#include + +import sm.hexgrid; +import sm.nm_simplex; +import sm.vec; +import sm.vvec; +import sm.random; + +import mplot.visual; +import mplot.triframevisual; +import mplot.hexgridvisual; // Here's the Rosenbrock banana function template @@ -46,7 +52,7 @@ int main() // Add a 'triangle visual' to be visualised as three rods sm::vec _offset = {0,0,0}; auto tfv = std::make_unique>(_offset); - v.bindmodel (tfv); + tfv->set_parent (v.get_id()); tfv->radius = 0.01f; tfv->sradius = 0.01f; std::vector tri_values(3, 0); @@ -68,13 +74,13 @@ int main() sm::hexgrid hg (0.01, 10, 0); hg.setCircularBoundary (2.5); std::vector banana_vals(hg.num(), 0.0f); - for (size_t i = 0; i < hg.num(); ++i) { + for (std::size_t i = 0; i < hg.num(); ++i) { banana_vals[i] = banana (hg.d_x[i], hg.d_y[i]); } sm::range mm = sm::range::get_from (banana_vals); std::cout << "Banana surface range: " << mm << std::endl; auto hgv = std::make_unique>(&hg, _offset); - v.bindmodel (hgv); + hgv->set_parent (v.get_id()); hgv->hexVisMode = mplot::HexVisMode::Triangles; hgv->cm.setType (mplot::ColourMapType::Viridis); hgv->setScalarData (&banana_vals); @@ -137,8 +143,8 @@ int main() v3 = { rng.get(), rng.get() }; i_vertices = { v1, v2, v3 }; - if (abs(thebest[0] - 1.0) < 1e-3 // Choose 1e-3 so that this will succeed with floats or doubles - && abs(thebest[1] - 1.0) < 1e-3) { + if (std::abs(thebest[0] - FLT{1}) < FLT{1e-3} // Choose 1e-3 so that this will succeed with floats or doubles + && std::abs(thebest[1] - FLT{1}) < FLT{1e-3}) { std::cout << "Test success" << std::endl; rtn = 0; } else { diff --git a/maths b/maths index 9cd8a796..e48eac19 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit 9cd8a79634d8e9c1f78d1a1470585d334a817663 +Subproject commit e48eac194d678518e94391abdf97ef88987b8d14 diff --git a/mplot/TriFrameVisual.h b/mplot/TriFrameVisual.cppm similarity index 76% rename from mplot/TriFrameVisual.h rename to mplot/TriFrameVisual.cppm index 699f6c4e..fe1f944f 100644 --- a/mplot/TriFrameVisual.h +++ b/mplot/TriFrameVisual.cppm @@ -1,17 +1,20 @@ -#pragma once +module; +#include #include #include #include #include +export module mplot.triframevisual; + import sm.vec; -#include -#include -#include +import mplot.tools; +import mplot.visualdatamodel; +import mplot.colourmap; -namespace mplot +export namespace mplot { /*! * The template argument Flt is the type of the data which this PointRowsMeshVisual @@ -24,7 +27,7 @@ namespace mplot * \param _offset The offset within the mplot::Visual scene at which the model will * be drawn (used when rendering, not when creating the model's vertices) */ - template + template class TriFrameVisual : public VisualDataModel { public: @@ -41,8 +44,8 @@ namespace mplot this->indices.clear(); this->idx = 0; - unsigned int ncoords = this->dataCoords->size(); - unsigned int ndata = this->scalarData->size(); + std::uint32_t ncoords = this->dataCoords->size(); + std::uint32_t ndata = this->scalarData->size(); std::vector dcopy; if (ndata) { @@ -52,14 +55,14 @@ namespace mplot } // else no scaling required - spheres will be one colour // Draw spheres - for (unsigned int i = 0U; i < ncoords; ++i) { + for (std::uint32_t i = 0U; i < ncoords; ++i) { this->computeSphere ((*this->dataCoords)[i], this->cm.convert ((*this->scalarData)[i]), sradius); } // Draw tubes std::array clr = {0.3f,0.3f,0.3f}; - for (unsigned int i = 0U; i < ncoords; ++i) { + for (std::uint32_t i = 0U; i < ncoords; ++i) { sm::vec v1 = (*this->dataCoords)[i]; - unsigned int e = (i < (ncoords-1) ? i+1 : 0); + std::uint32_t e = (i < (ncoords-1) ? i+1 : 0); sm::vec v2 = (*this->dataCoords)[e]; sm::vec _offset = this->viewmatrix.translation(); this->computeTube (_offset + v1, _offset + v2, clr, clr, this->radius, this->tseg); @@ -71,11 +74,11 @@ namespace mplot //! sphere radius float sradius = 0.052f; //! sphere rings - int srings = 10; + std::int32_t srings = 10; //! sphere segments - int sseg = 12; + std::int32_t sseg = 12; //! tube segments - int tseg = 12; + std::int32_t tseg = 12; //! A colour map for the spheres mplot::ColourMap cm_sph; }; From 5381db6493a2630a78bb0e41b3a78a79cc40fadb Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 27 Mar 2026 11:40:35 +0000 Subject: [PATCH 102/106] Changes after de-camelcasing sebsjames/maths --- examples/hexgrid.cpp | 2 +- examples/rosenbrock.cpp | 4 +- examples/showcase.cpp | 8 +- examples/visual.cpp | 6 +- maths | 2 +- mplot/HexGridVisual.cppm | 178 +++++++++++++++++++-------------------- 6 files changed, 100 insertions(+), 100 deletions(-) diff --git a/examples/hexgrid.cpp b/examples/hexgrid.cpp index ee47a7c8..f2f09f95 100644 --- a/examples/hexgrid.cpp +++ b/examples/hexgrid.cpp @@ -36,7 +36,7 @@ int main() // Create a HexGrid to show in the scene. Hexes outside the circular boundary will // all be discarded. sm::hexgrid hg(0.01f, 3.0f, 0.0f); - hg.setCircularBoundary (0.6f); + hg.set_circular_boundary (0.6f); std::cout << "Number of pixels in grid:" << hg.num() << std::endl; diff --git a/examples/rosenbrock.cpp b/examples/rosenbrock.cpp index 6243218e..0f8fcf6b 100644 --- a/examples/rosenbrock.cpp +++ b/examples/rosenbrock.cpp @@ -72,7 +72,7 @@ int main() // Evaluate banana function and plot sm::hexgrid hg (0.01, 10, 0); - hg.setCircularBoundary (2.5); + hg.set_circular_boundary (2.5); std::vector banana_vals(hg.num(), 0.0f); for (std::size_t i = 0; i < hg.num(); ++i) { banana_vals[i] = banana (hg.d_x[i], hg.d_y[i]); @@ -109,7 +109,7 @@ int main() std::chrono::steady_clock::time_point lastoptstep = std::chrono::steady_clock::now(); // Now step until the algorithm is ready to finish - while (simp.state != sm::nm_simplex_state::ReadyToStop && !v.readyToFinish()) { + while (simp.state != sm::nm_simplex_state::ready_to_stop && !v.readyToFinish()) { // Perform optimisation steps slowly std::chrono::steady_clock::duration sinceoptstep = std::chrono::steady_clock::now() - lastoptstep; diff --git a/examples/showcase.cpp b/examples/showcase.cpp index e1b4b7c3..27b3da41 100644 --- a/examples/showcase.cpp +++ b/examples/showcase.cpp @@ -119,18 +119,18 @@ int main() */ { sm::hexgrid hg(0.06f, 3.0f, 0.0f); - hg.setCircularBoundary (0.6f); + hg.set_circular_boundary (0.6f); // Make some dummy data (a sine wave) to make an interesting surface std::vector data(hg.num(), 0.0f); - for (unsigned int ri=0; ri1 } - auto hgv = std::make_unique>(&hg, sm::vec({-2,-0.5,0})); + auto hgv = std::make_unique>(&hg, sm::vec{-2.0f, -0.5f, 0.0f}); hgv->set_parent (v.get_id()); hgv->setScalarData (&data); hgv->cm.setType (mplot::ColourMapType::Inferno); hgv->hexVisMode = mplot::HexVisMode::HexInterp; // Or mplot::HexVisMode::Triangles for a smoother surface plot - hgv->addLabel ("mplot::HexGridVisual", sm::vec({0,-0.7,0}), mplot::TextFeatures(0.05)); + hgv->addLabel ("mplot::HexGridVisual", sm::vec{0.0f, -0.7f, 0.0f}, mplot::TextFeatures(0.05f)); hgv->finalize(); v.addVisualModel (hgv); } diff --git a/examples/visual.cpp b/examples/visual.cpp index 26c9047f..c6d8f671 100644 --- a/examples/visual.cpp +++ b/examples/visual.cpp @@ -43,13 +43,13 @@ int main() // Create a hexgrid to show in the scene sm::hexgrid hg(0.01, 3, 0); - hg.setCircularBoundary (0.3); + hg.set_circular_boundary (0.3); std::cout << "Number of hexes in grid:" << hg.num() << std::endl; // Make some dummy data (a sine wave) to make an interesting surface std::vector data(hg.num(), 0.0); - for (unsigned int hi=0; hi1 + for (unsigned int hi = 0; hi < hg.num(); ++hi) { + data[hi] = 0.05f + 0.05f * std::sin (10.0f * hg.d_x[hi]); // Range 0->1 } // Add a HexGridVisual to display the hexgrid within the mplot::Visual scene diff --git a/maths b/maths index e48eac19..ac396943 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit e48eac194d678518e94391abdf97ef88987b8d14 +Subproject commit ac3969434e9b2e7a29df3b44709ad70d0175d450 diff --git a/mplot/HexGridVisual.cppm b/mplot/HexGridVisual.cppm index f5cf09b6..c0b74813 100644 --- a/mplot/HexGridVisual.cppm +++ b/mplot/HexGridVisual.cppm @@ -230,9 +230,9 @@ export namespace mplot { // Here's a complication. In a transformed grid, we can't rely on these. Should be able // to *compute* them though. - float sr = this->hg->getSR(); - float vne = this->hg->getVtoNE(); - float lr = this->hg->getLR(); + float sr = this->hg->get_sr(); + float vne = this->hg->get_v_to_ne(); + float lr = this->hg->get_lr(); uint32_t nhex = this->hg->num(); @@ -301,7 +301,7 @@ export namespace mplot // Use a single colour for each hex, even though hex z positions are // interpolated. Do the _colour_ scaling: std::array clr = this->setColour (hi); - if (this->showboundary && (this->hg->vhexen[hi])->boundaryHex() == true) { + if (this->showboundary && (this->hg->vhexen[hi])->boundary_hex() == true) { this->markHex (hi); } if (this->showcentre && _x == 0.0f && _y == 0.0f) { @@ -580,9 +580,9 @@ export namespace mplot // rectangle of two triangles. void computeZerogridIndices() { - float sr = this->hg->getSR(); - float vne = this->hg->getVtoNE(); - float lr = this->hg->getLR(); + float sr = this->hg->get_sr(); + float vne = this->hg->get_v_to_ne(); + float lr = this->hg->get_lr(); uint32_t nhex = this->hg->num(); sm::vec vtx_0, vtx_1, vtx_2; @@ -677,9 +677,9 @@ export namespace mplot std::array blk = { 0, 0, 0 }; sm::vec uz = {0.0f, 0.0f, 1.0f}; - float sw = this->hg->getd()/80.0f; // sphere radius (~width) - float lw = this->hg->getd()/40.0f; // line width - float lh = this->hg->getd()/60.0f; // line height + float sw = this->hg->get_d()/80.0f; // sphere radius (~width) + float lw = this->hg->get_d()/40.0f; // line width + float lh = this->hg->get_d()/60.0f; // line height // Vertices and lines of base hexagon this->computeSphere (this->hg->sw_loc.plus_one_dim(), clr, sw, 14, 12); @@ -794,34 +794,34 @@ export namespace mplot clr = blk; if (!this->hg->p1.has_nan() && !this->hg->q1.has_nan() && !this->hg->p2.has_nan() && !this->hg->q2.has_nan()) { - this->computeLine (this->hg->p1.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), - this->hg->q1.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), + this->computeLine (this->hg->p1.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), + this->hg->q1.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), uz, blk, blk, lw/2.0f, lh); - this->computeLine (this->hg->p2.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), - this->hg->q2.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), + this->computeLine (this->hg->p2.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), + this->hg->q2.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), uz, blk, blk, lw/2.0f, lh); } // finding i5 if (!this->hg->p3.has_nan() && !this->hg->q3.has_nan() && !this->hg->p4.has_nan() && !this->hg->q4.has_nan()) { - this->computeLine (this->hg->p3.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), - this->hg->q3.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), + this->computeLine (this->hg->p3.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), + this->hg->q3.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), uz, blk, blk, lw/2.0f, lh); - this->computeLine (this->hg->p4.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), - this->hg->q4.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), + this->computeLine (this->hg->p4.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), + this->hg->q4.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), uz, blk, blk, lw/2.0f, lh); } // intersection points - sw = this->hg->getd()/40.0f; + sw = this->hg->get_d()/40.0f; if (!this->hg->i1.has_nan()) { clr = {1,0,0}; this->computeSphere (this->hg->i1.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("i1", (this->hg->i1).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("i1", (this->hg->i1).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); clr = {0,0,0}; } if (!this->hg->i2.has_nan()) { @@ -835,202 +835,202 @@ export namespace mplot } if (!this->hg->i5.has_nan()) { this->computeSphere (this->hg->i5.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("i5", (this->hg->i5).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("i5", (this->hg->i5).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); } // p/q points used to compute additional pgrams if (!this->hg->q2.has_nan()) { clr = {0,0,1}; this->computeSphere (this->hg->q2.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("q2", (this->hg->q2).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("q2", (this->hg->q2).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); } if (!this->hg->q1.has_nan()) { clr = {0,1,0}; this->computeSphere (this->hg->q1.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("q1", (this->hg->q1).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("q1", (this->hg->q1).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); } if (!this->hg->q3.has_nan()) { clr = {0,0,1}; this->computeSphere (this->hg->q3.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("q3", (this->hg->q3).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("q3", (this->hg->q3).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); } if (!this->hg->q4.has_nan()) { clr = {0,1,0}; this->computeSphere (this->hg->q4.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("q4", (this->hg->q4).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("q4", (this->hg->q4).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); } if (!this->hg->q5.has_nan()) { clr = {0,1,0}; this->computeSphere (this->hg->q5.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("q5", (this->hg->q5).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("q5", (this->hg->q5).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); } if (!this->hg->q6.has_nan()) { clr = {0,1,0}; this->computeSphere (this->hg->q6.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("q6", (this->hg->q6).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("q6", (this->hg->q6).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); } if (!this->hg->q7.has_nan()) { clr = {0,1,0}; this->computeSphere (this->hg->q7.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("q7", (this->hg->q7).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("q7", (this->hg->q7).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); } if (!this->hg->q8.has_nan()) { clr = {0,1,0}; this->computeSphere (this->hg->q8.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("q8", (this->hg->q8).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("q8", (this->hg->q8).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); } #if 1 // 60/300 units vectors if (!this->hg->i1.has_nan() && !this->hg->unit_60.has_nan()) { clr = {1,0,0}; - this->computeLine (this->hg->i1.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), - (this->hg->i1+this->hg->unit_60).plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), + this->computeLine (this->hg->i1.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), + (this->hg->i1+this->hg->unit_60).plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), uz, clr, clr, lw/2.0f, lh); } if (!this->hg->i5.has_nan() && !this->hg->unit_300.has_nan()) { clr = {0,0,0}; - this->computeLine (this->hg->i5.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), - (this->hg->i5+this->hg->unit_300).plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), + this->computeLine (this->hg->i5.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), + (this->hg->i5+this->hg->unit_300).plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), uz, clr, clr, lw/2.0f, lh); } if (!this->hg->i1.has_nan() && !this->hg->unit_120.has_nan()) { clr = {1,0,0}; - this->computeLine (this->hg->i1.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), - (this->hg->i1+this->hg->unit_120).plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), + this->computeLine (this->hg->i1.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), + (this->hg->i1+this->hg->unit_120).plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), uz, clr, clr, lw/2.0f, lh); } #endif if (!this->hg->p1.has_nan()) { clr = {0,1,0}; this->computeSphere (this->hg->p1.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("p1", (this->hg->p1).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("p1", (this->hg->p1).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); } if (!this->hg->p2.has_nan()) { clr = {0,0,1}; this->computeSphere (this->hg->p2.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("p2", (this->hg->p2).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("p2", (this->hg->p2).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); } if (!this->hg->p3.has_nan()) { clr = {0,0,1}; this->computeSphere (this->hg->p3.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("p3", (this->hg->p3).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("p3", (this->hg->p3).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); } if (!this->hg->p4.has_nan()) { clr = {0,1,0}; this->computeSphere (this->hg->p4.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("p4", (this->hg->p4).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("p4", (this->hg->p4).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); } if (!this->hg->p5.has_nan()) { clr = {0,1,0}; this->computeSphere (this->hg->p5.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("p5", (this->hg->p5).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("p5", (this->hg->p5).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); } if (!this->hg->p6.has_nan()) { clr = {0,1,0}; this->computeSphere (this->hg->p6.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("p6", (this->hg->p6).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("p6", (this->hg->p6).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); } if (!this->hg->p8.has_nan()) { clr = {0,1,0}; this->computeSphere (this->hg->p8.plus_one_dim(), clr, sw, 14, 12); - this->addLabel ("p8", (this->hg->p8).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->getd(), - mplot::TextFeatures(0.1f * this->hg->getd(), 48, clr)); + this->addLabel ("p8", (this->hg->p8).plus_one_dim()+sm::vec({sw,0,0.02}) * this->hg->get_d(), + mplot::TextFeatures(0.1f * this->hg->get_d(), 48, clr)); } // Draw grey triangles/rects for the relevant areas clr = {0.5f, 0.5f, 0.5f}; // t1 if (!this->hg->a1_tl.has_nan() && !this->hg->i1.has_nan() && !this->hg->i2.has_nan()) { - this->computeLine (this->hg->a1_tl.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), - this->hg->i1.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), + this->computeLine (this->hg->a1_tl.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), + this->hg->i1.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), uz, clr, clr, lw/2.0f, lh); - this->computeLine (this->hg->i1.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), - this->hg->i2.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), + this->computeLine (this->hg->i1.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), + this->hg->i2.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), uz, clr, clr, lw/2.0f, lh); - this->computeLine (this->hg->i2.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), - this->hg->a1_tl.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), + this->computeLine (this->hg->i2.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), + this->hg->a1_tl.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), uz, clr, clr, lw/2.0f, lh); } // t2 if (!this->hg->a1_bl.has_nan() && !this->hg->i3.has_nan() && !this->hg->i4.has_nan()) { - this->computeLine (this->hg->a1_bl.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), - this->hg->i3.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), + this->computeLine (this->hg->a1_bl.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), + this->hg->i3.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), uz, clr, clr, lw/2.0f, lh); - this->computeLine (this->hg->i3.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), - this->hg->i4.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), + this->computeLine (this->hg->i3.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), + this->hg->i4.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), uz, clr, clr, lw/2.0f, lh); - this->computeLine (this->hg->i4.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), - this->hg->a1_bl.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), + this->computeLine (this->hg->i4.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), + this->hg->a1_bl.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), uz, clr, clr, lw/2.0f, lh); } // Sides of a1 if (!this->hg->a1_bl.has_nan() && !this->hg->i2.has_nan() && !this->hg->i3.has_nan()) { - this->computeLine (this->hg->a1_bl.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), - this->hg->a1_bl.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), + this->computeLine (this->hg->a1_bl.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), + this->hg->a1_bl.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), uz, clr, clr, lw/2.0f, lh); - this->computeLine (this->hg->i2.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), - this->hg->i3.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), + this->computeLine (this->hg->i2.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), + this->hg->i3.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), uz, clr, clr, lw/2.0f, lh); } // Side of the central rectangle, from i5 and up if (!this->hg->i5.has_nan() && !this->hg->i6.has_nan()) { - this->computeLine (this->hg->i5.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), - this->hg->i6.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->getd(), + this->computeLine (this->hg->i5.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), + this->hg->i6.plus_one_dim()+sm::vec({0,0,0.02}) * this->hg->get_d(), uz, clr, clr, lw/2.0f, lh); } // Parallel and rectangle vertices. Do vert cylinders if (!this->hg->pll1_top.has_nan()) { clr = mplot::colour::magenta2; - this->computeTube (this->hg->pll1_top.plus_one_dim()+sm::vec({0,0,0.1}) * this->hg->getd(), - this->hg->pll1_top.plus_one_dim()+sm::vec({0,0,-0.1}) * this->hg->getd(), + this->computeTube (this->hg->pll1_top.plus_one_dim()+sm::vec({0,0,0.1}) * this->hg->get_d(), + this->hg->pll1_top.plus_one_dim()+sm::vec({0,0,-0.1}) * this->hg->get_d(), clr, clr, lw/4.0f); } if (!this->hg->pll1_br.has_nan()) { clr = mplot::colour::deeppink2; - this->computeTube (this->hg->pll1_br.plus_one_dim()+sm::vec({0,0,0.1}) * this->hg->getd(), - this->hg->pll1_br.plus_one_dim()+sm::vec({0,0,-0.1}) * this->hg->getd(), + this->computeTube (this->hg->pll1_br.plus_one_dim()+sm::vec({0,0,0.1}) * this->hg->get_d(), + this->hg->pll1_br.plus_one_dim()+sm::vec({0,0,-0.1}) * this->hg->get_d(), clr, clr, lw/4.0f); } if (!this->hg->pll2_bot.has_nan()) { clr = mplot::colour::dodgerblue2; - this->computeTube (this->hg->pll2_bot.plus_one_dim()+sm::vec({0,0,0.1}) * this->hg->getd(), - this->hg->pll2_bot.plus_one_dim()+sm::vec({0,0,-0.1}) * this->hg->getd(), + this->computeTube (this->hg->pll2_bot.plus_one_dim()+sm::vec({0,0,0.1}) * this->hg->get_d(), + this->hg->pll2_bot.plus_one_dim()+sm::vec({0,0,-0.1}) * this->hg->get_d(), clr, clr, lw/4.0f); } if (!this->hg->pll2_tr.has_nan()) { clr = mplot::colour::darkgreen; - this->computeTube (this->hg->pll2_tr.plus_one_dim()+sm::vec({0,0,0.1}) * this->hg->getd(), - this->hg->pll2_tr.plus_one_dim()+sm::vec({0,0,-0.1}) * this->hg->getd(), + this->computeTube (this->hg->pll2_tr.plus_one_dim()+sm::vec({0,0,0.1}) * this->hg->get_d(), + this->hg->pll2_tr.plus_one_dim()+sm::vec({0,0,-0.1}) * this->hg->get_d(), clr, clr, lw/4.0f); } if (!this->hg->a1_tl.has_nan()) { clr = mplot::colour::yellow; - this->computeTube (this->hg->a1_tl.plus_one_dim()+sm::vec({0,0,0.1}) * this->hg->getd(), - this->hg->a1_tl.plus_one_dim()+sm::vec({0,0,-0.1}) * this->hg->getd(), + this->computeTube (this->hg->a1_tl.plus_one_dim()+sm::vec({0,0,0.1}) * this->hg->get_d(), + this->hg->a1_tl.plus_one_dim()+sm::vec({0,0,-0.1}) * this->hg->get_d(), clr, clr, lw/4.0f); } if (!this->hg->a1_bl.has_nan()) { clr = mplot::colour::green; - this->computeTube (this->hg->a1_bl.plus_one_dim()+sm::vec({0,0,0.1}) * this->hg->getd(), - this->hg->a1_bl.plus_one_dim()+sm::vec({0,0,-0.1}) * this->hg->getd(), + this->computeTube (this->hg->a1_bl.plus_one_dim()+sm::vec({0,0,0.1}) * this->hg->get_d(), + this->hg->a1_bl.plus_one_dim()+sm::vec({0,0,-0.1}) * this->hg->get_d(), clr, clr, lw/4.0f); } } From 5da3ca9c59dfb0fba6542404fd849b51f8282c56 Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 27 Mar 2026 11:54:50 +0000 Subject: [PATCH 103/106] scaling_function was de-camelCased --- mplot/QuiverVisual.cppm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mplot/QuiverVisual.cppm b/mplot/QuiverVisual.cppm index 5b4dce80..ec2c3d36 100644 --- a/mplot/QuiverVisual.cppm +++ b/mplot/QuiverVisual.cppm @@ -91,7 +91,7 @@ export namespace mplot // Now scale the lengths for their size on screen. Do this with a linear or log scaling. // (if log) First replace zeros with NaNs so that log transform will work. - if (this->do_quiver_length_scaling == true && this->length_scale.get_type() == sm::scaling_function::Logarithmic) { + if (this->do_quiver_length_scaling == true && this->length_scale.get_type() == sm::scaling_function::logarithmic) { dlengths.search_replace (Flt{0}, std::numeric_limits::quiet_NaN()); } From 2dce8b464c22bda7a1e9217a010703f9c08142cd Mon Sep 17 00:00:00 2001 From: Seb James Date: Fri, 27 Mar 2026 17:15:44 +0000 Subject: [PATCH 104/106] Adds a reinitColours for rodVisual --- mplot/RodVisual.cppm | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/mplot/RodVisual.cppm b/mplot/RodVisual.cppm index 15ab7f27..1eca5ac4 100644 --- a/mplot/RodVisual.cppm +++ b/mplot/RodVisual.cppm @@ -81,6 +81,28 @@ export namespace mplot this->reinit(); } + //! reinit just the colours based on vvec data + void reinitColours() + { + std::size_t n_cfloats = this->vertexColors.size(); + if (n_cfloats == 0u) { return; } // model doesn't exist yet + + // Do start, then end + for (std::size_t i = 0; i < n_cfloats/2; i += 3) { + this->vertexColors[i] = this->start_col[0]; + this->vertexColors[i + 1] = this->start_col[1]; + this->vertexColors[i + 2] = this->start_col[2]; + } + for (std::size_t i = n_cfloats/2; i < n_cfloats; i += 3) { + this->vertexColors[i] = this->end_col[0]; + this->vertexColors[i + 1] = this->end_col[1]; + this->vertexColors[i + 2] = this->end_col[2]; + } + + // Lastly, this call copies vertexColors (etc) into the OpenGL memory space + this->reinit_colour_buffer(); + } + //! The position of the start of the rod, given with respect to the parent's offset sm::vec start_coord = {0.0f, 0.0f, 0.0f}; //! The position of the end of the rod, given with respect to the parent's offset From 785ecc1c2680636707e8ac952cf3ba8cfd02be32 Mon Sep 17 00:00:00 2001 From: Seb James Date: Mon, 30 Mar 2026 10:00:59 +0100 Subject: [PATCH 105/106] Adds a colour match convenience function --- mplot/colour.cppm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mplot/colour.cppm b/mplot/colour.cppm index a7aff5fd..02b23c68 100644 --- a/mplot/colour.cppm +++ b/mplot/colour.cppm @@ -12,6 +12,8 @@ export module mplot.colour; export namespace mplot::colour { + constexpr bool match (const std::array& c1, const std::array& c2) { return c1 == c2; } + constexpr std::array indian_red = {0.6901960784f,0.0901960784f,0.1215686275f}; constexpr std::array crimson = {0.862745098f,0.0784313725f,0.2352941176f}; constexpr std::array lightpink = {1.0f,0.7137254902f,0.7568627451f}; From ff8daeee2c849436de0fa8565ea871858e329ab9 Mon Sep 17 00:00:00 2001 From: Seb James Date: Mon, 30 Mar 2026 14:58:42 +0100 Subject: [PATCH 106/106] standard ints in ColourMap, the uint32_t to array colour conversion function in the mplot::colour namespace --- mplot/ColourMap.cppm | 46 ++++++++++++++++++++++---------------------- mplot/colour.cppm | 7 +++++++ 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/mplot/ColourMap.cppm b/mplot/ColourMap.cppm index e3291009..12e36421 100644 --- a/mplot/ColourMap.cppm +++ b/mplot/ColourMap.cppm @@ -21,7 +21,7 @@ import sm.crc32; export namespace mplot { //! Different colour maps types. - enum class ColourMapType : uint32_t + enum class ColourMapType : std::uint32_t { // Python matplotlib maps Magma, @@ -188,19 +188,19 @@ export namespace mplot // Define prefix increment and decrement operators for the ColourMapType enum class. mplot::ColourMapType& operator++(mplot::ColourMapType& t) { - t = static_cast((static_cast(t) + 1u) % static_cast(mplot::ColourMapType::N_entries)); + t = static_cast((static_cast(t) + 1u) % static_cast(mplot::ColourMapType::N_entries)); return t; } mplot::ColourMapType& operator--(mplot::ColourMapType& t) { - uint32_t ti = static_cast(t); - ti = (ti == 0u ? static_cast(mplot::ColourMapType::N_entries) - 1u : ti - 1u); + std::uint32_t ti = static_cast(t); + ti = (ti == 0u ? static_cast(mplot::ColourMapType::N_entries) - 1u : ti - 1u); t = static_cast(ti); return t; } // A flags class for ColourMaps, to flag features - enum class ColourMapFlags : uint32_t + enum class ColourMapFlags : std::uint32_t { one_d, two_d, @@ -228,7 +228,7 @@ export namespace mplot sm::flags makeColourMapFlags (const mplot::ColourMapType t) { // Logic to create default flags - sm::flags f(uint32_t{0}); + sm::flags f(std::uint32_t{0}); // Dimensionality if (t == ColourMapType::DiscFourWhite @@ -586,7 +586,7 @@ export namespace mplot ColourMapType cmt = mplot::ColourMapType::Plasma; std::string _s = s; mplot::tools::toLowerCase (_s); - uint32_t _s_crc = sm::crc32 (_s); + std::uint32_t _s_crc = sm::crc32 (_s); switch (_s_crc) { case sm::crc32 ("fixed"sv): cmt = mplot::ColourMapType::Fixed; break; @@ -1669,9 +1669,9 @@ export namespace mplot } //! How many colour datums does the colour map require? - static int numDatums (ColourMapType _t, bool _act_2d = false) + static std::int32_t numDatums (ColourMapType _t, bool _act_2d = false) { - int n = 0; + std::int32_t n = 0; switch (_t) { case ColourMapType::Trichrome: case ColourMapType::RGB: @@ -1700,7 +1700,7 @@ export namespace mplot return n; } - int numDatums() const { return ColourMap::numDatums (this->type, this->act_2d); } + std::int32_t numDatums() const { return ColourMap::numDatums (this->type, this->act_2d); } //! The maximum number for the range of the datum to convert to a colour. 1 for //! floating point variables. @@ -1715,12 +1715,12 @@ export namespace mplot rm = 127; } else if constexpr (std::is_same, bool>::value == true) { rm = true; - } else if constexpr (std::is_same, unsigned short>::value == true - || std::is_same, short>::value == true - || std::is_same, unsigned int>::value == true - || std::is_same, int>::value == true - || std::is_same, unsigned long long int>::value == true - || std::is_same, long long int>::value == true) { + } else if constexpr (std::is_same, std::uint16_t>::value == true + || std::is_same, std::int16_t>::value == true + || std::is_same, std::uint32_t>::value == true + || std::is_same, std::int32_t>::value == true + || std::is_same, std::uint64_t>::value == true + || std::is_same, std::int64_t>::value == true) { // For long types, default to 8 bit input; user can change afterwards. rm = 255; } @@ -2924,7 +2924,7 @@ export namespace mplot } //! Set this->hue, sat and val from the passed in RGB hex value (e.g. 0xff00ff for magenta) - void setRGB (const uint32_t rgb) { this->setRGB (ColourMap::rgb_array (rgb)); } + void setRGB (const std::uint32_t rgb) { this->setRGB (ColourMap::rgb_array (rgb)); } //! Get the hue, in its most saturated form std::array getHueRGB() const { return ColourMap::hsv2rgb (this->hue, 1.0f, 1.0f); } @@ -2981,7 +2981,7 @@ export namespace mplot static std::array hsv2rgb (float h, float s, float v) { std::array rgb = { 0.0f, 0.0f, 0.0f }; - int i = floor(h * 6); + std::int32_t i = floor(h * 6); float f = h * 6.0f - i; float p = v * (1.0f - s); float q = v * (1.0f - f * s); @@ -3004,8 +3004,8 @@ export namespace mplot return ColourMap::rgb2hsv (rgb[0], rgb[1], rgb[2]); } - //! Convert RGB (given as uint32_t) to HSV, receiving input and returning output as std::array - static std::array rgb2hsv (const uint32_t rgb) + //! Convert RGB (given as std::uint32_t) to HSV, receiving input and returning output as std::array + static std::array rgb2hsv (const std::uint32_t rgb) { return ColourMap::rgb2hsv (ColourMap::rgb_array (rgb)); } @@ -3018,8 +3018,8 @@ export namespace mplot return hsv; } - //! Convert RGB (given as uint32_t) to HSV, returning output as sm::vec - static sm::vec rgb2hsv_vec (const uint32_t rgb) + //! Convert RGB (given as std::uint32_t) to HSV, returning output as sm::vec + static sm::vec rgb2hsv_vec (const std::uint32_t rgb) { sm::vec hsv = {}; hsv.set_from (ColourMap::rgb2hsv (ColourMap::rgb_array (rgb))); @@ -3072,7 +3072,7 @@ export namespace mplot } // Convert hex colour value (e.g. 0x2971c3) into our usual array of floats in range [0, 1] - static std::array rgb_array (const uint32_t rgb) + static std::array rgb_array (const std::uint32_t rgb) { return std::array{ ((rgb >> 16) & 0xff) / 255.0f, ((rgb >> 8) & 0xff) / 255.0f, (rgb & 0xff) / 255.0f }; } diff --git a/mplot/colour.cppm b/mplot/colour.cppm index 02b23c68..eab13c07 100644 --- a/mplot/colour.cppm +++ b/mplot/colour.cppm @@ -7,6 +7,7 @@ * Date: Nov 2020 */ module; +#include #include export module mplot.colour; @@ -14,6 +15,12 @@ export namespace mplot::colour { constexpr bool match (const std::array& c1, const std::array& c2) { return c1 == c2; } + // Convert hex colour value (e.g. 0x2971c3) into an array of floats in range [0, 1]. Same as ColourMap<>::rgb_array + constexpr std::array rgb_array (const std::uint32_t rgb) + { + return std::array{ ((rgb >> 16) & 0xff) / 255.0f, ((rgb >> 8) & 0xff) / 255.0f, (rgb & 0xff) / 255.0f }; + } + constexpr std::array indian_red = {0.6901960784f,0.0901960784f,0.1215686275f}; constexpr std::array crimson = {0.862745098f,0.0784313725f,0.2352941176f}; constexpr std::array lightpink = {1.0f,0.7137254902f,0.7568627451f};