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 8280c82f..9a9cd024 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,12 @@ -cmake_minimum_required(VERSION 3.14) -project(mathplot) +cmake_minimum_required(VERSION 3.28.5) +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}") 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() @@ -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/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... 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 cb4592b9..a2b4d2e1 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,33 +1,585 @@ -# 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() +# All #includes in test programs have to be #include +include_directories(BEFORE ${PROJECT_SOURCE_DIR}) -# Examples showing how to use mathplot with Qt. Compiled only if -# find_package found Qt5 -if(Qt5_FOUND) - add_subdirectory(qt) -endif() +# 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/geometry + ${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}/maths/sm/crc32 + ${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/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 + + ${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/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 + + PROPERTIES LANGUAGE CXX +) -# Disabled as haven't figured out a GL multi-context scheme for wx windows -#if(wxWidgets_FOUND) -# add_subdirectory(wx) -#endif() +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 + ${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) +target_link_libraries(helloworld OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) -if (OpenGL_EGL_FOUND) - add_subdirectory(pi) +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 + ${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) +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}/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(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}/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/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() -# All #includes in test programs have to be #include -include_directories(BEFORE ${PROJECT_SOURCE_DIR}) +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}/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) -# Screenshots used in the documentation/reference website -if(BUILD_DOC_SCREENSHOTS) - add_subdirectory(docs) +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}/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) +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/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 + ${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} + 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}/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 + ${PROJECT_SOURCE_DIR}/maths/sm/grid +) +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/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 + ${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 + ) + 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} + 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/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}/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(showcase OpenGL::GL glfw Freetype::Freetype glad mplot_fontdata) +endif(ARMADILLO_FOUND) +endif (0) + +if(0) # During development + # # Any example that uses sm::hexgrid or sm::cartgrid requires # libarmadillo (because the classes use sm::BezCurve). @@ -141,24 +693,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_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_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) @@ -232,9 +774,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) @@ -334,9 +873,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_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) @@ -558,3 +1094,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/breadcrumbs.cpp b/examples/breadcrumbs.cpp index a19d0634..61a62e65 100644 --- a/examples/breadcrumbs.cpp +++ b/examples/breadcrumbs.cpp @@ -1,19 +1,22 @@ /* * Visualize a test surface */ +#include #include #include #include #include -#include -#include -#include +#include +import sm.scale; +import sm.vec; +import sm.vvec; -#include -#include -#include -#include +import mplot.visual; +import mplot.colourmap; + +import mplot.instancedscattervisual; +import mplot.geodesicvisual; // Instanced rendering requires OpenGL 4.3 or higher (for the SSBO) constexpr int glver = mplot::gl::version_4_3; @@ -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/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/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/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/examples/graph1.cpp b/examples/graph1.cpp index eafda6ce..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 -#include -#include +#include +import mplot.visual; +import mplot.graphvisual; // exports sm.vvec and sm.vec 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/grid_simple.cpp b/examples/grid_simple.cpp index 1e8d43cf..13a7f204 100644 --- a/examples/grid_simple.cpp +++ b/examples/grid_simple.cpp @@ -5,13 +5,17 @@ #include #include #include +#include -#include -#include +import sm.vec; +import sm.grid; -#include -#include -#include +import mplot.visual; +import mplot.gl.version; +import mplot.visualmodel; +import mplot.textfeatures; +import mplot.gridvisual; +import mplot.colourmap; 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/helloworld.cpp b/examples/helloworld.cpp index c0fd0bad..55244ca5 100644 --- a/examples/helloworld.cpp +++ b/examples/helloworld.cpp @@ -1,4 +1,6 @@ -#include +import mplot.visual; +import mplot.gl.version; + int main() { mplot::Visual v(600, 400, "Hello World!"); diff --git a/examples/rod.cpp b/examples/rod.cpp index 8df0e841..ad17ccca 100644 --- a/examples/rod.cpp +++ b/examples/rod.cpp @@ -2,17 +2,14 @@ * Visualize a Rod */ #include -#include -#include -#include -#include -#include +#include -#include +import sm.vec; -#include -#include -#include +import mplot.visual; +import mplot.gl.version; +import mplot.colourmap; +import mplot.rodvisual; int main() { @@ -27,32 +24,30 @@ 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 }; + + 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 }; + 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); + rvm->set_parent (v.get_id()); + rvm->finalize(); + std::cout << "addVisualmodel...\n" << std::flush; + v.addVisualModel (rvm); + + v.keepOpen(); return rtn; } 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/examples/showcase.cpp b/examples/showcase.cpp index d54a41ce..50f965cf 100644 --- a/examples/showcase.cpp +++ b/examples/showcase.cpp @@ -1,12 +1,13 @@ // A showcase of different visual models -#include +import sm.vvec; +import sm.grid; + #include #include -#include #include -#include +import mplot.visual; #include #include #include 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/json b/json new file mode 160000 index 00000000..f534f4f7 --- /dev/null +++ b/json @@ -0,0 +1 @@ +Subproject commit f534f4f75e12893716ea688679aeb768bff426c4 diff --git a/maths b/maths index ab7b1595..449d125b 160000 --- a/maths +++ b/maths @@ -1 +1 @@ -Subproject commit ab7b1595ee6f2cb44063a4ee1c736f5ac9a1a7e5 +Subproject commit 449d125b77d81b54bad73620e85fe2412e5be8a1 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/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..43e24e0e 100644 --- a/mplot/ColourMap.h +++ b/mplot/ColourMap.h @@ -1,22 +1,25 @@ -#pragma once +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 #include -#include -#include #include -#include -#include -namespace mplot +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; +import sm.crc32; + +export namespace mplot { //! Different colour maps types. enum class ColourMapType : uint32_t 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/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/CoordArrows.h b/mplot/CoordArrows.h index c64877f9..019f48ca 100644 --- a/mplot/CoordArrows.h +++ b/mplot/CoordArrows.h @@ -1,20 +1,26 @@ /*! * \file * - * Defines a coordinate arrow class + * Defines a coordinate arrow class based on VisualModel * * \author Seb James * \date 2019 */ -#pragma once +module; #include -#include -#include -#include -#include +#include -namespace mplot +export module mplot.coordarrows; + +import sm.vec; +import mplot.gl.version; +export import mplot.visualmodel; +export import mplot.textfeatures; +import mplot.visualfont; +export import mplot.colour; + +export namespace mplot { //! This class creates the vertices for a set of coordinate arrows to be rendered //! in a 3-D scene. @@ -53,13 +59,13 @@ namespace mplot this->reinit(); // sets context, does not release it // Give the text labels a suitable, visible colour - if (this->setContext != nullptr) { this->setContext (this->parentVis); } + mplot::VisualResources::i().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); } + mplot::VisualResources::i().releaseContext(); } } @@ -67,8 +73,7 @@ namespace mplot { if (this->em > 0.0f) { - if (this->setContext != nullptr) { this->setContext (this->parentVis); } // For VisualTextModel - + 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 @@ -90,7 +95,7 @@ namespace mplot vtm3->setupText (this->z_label, toffset); this->texts.push_back (std::move(vtm3)); - if (this->releaseContext != nullptr) { this->releaseContext (this->parentVis); } + mplot::VisualResources::i().releaseContext(); } } 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..1013cfdf 100644 --- a/mplot/DatasetStyle.h +++ b/mplot/DatasetStyle.h @@ -1,14 +1,19 @@ -#pragma once +module; #include #include -#include -#include -#include -#include -#include -namespace mplot +export module mplot.datasetstyle; + +import sm.vec; +import sm.flags; + +export import mplot.graphstyles; + +import mplot.colourmap; +import mplot.colour; + +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/GeodesicVisual.h b/mplot/GeodesicVisual.h index d6b6ea18..d37d41d9 100644 --- a/mplot/GeodesicVisual.h +++ b/mplot/GeodesicVisual.h @@ -1,14 +1,20 @@ -#pragma once +module; #include -#include -#include -#include -#include -#include -#include - -namespace mplot +#include + +export module mplot.geodesicvisual; + +export import sm.vec; +export import sm.vvec; +export import sm.scale; +import sm.geometry; +import sm.geometry_polyhedra; + +export import mplot.visualmodel; +export import mplot.colourmap; + +export namespace mplot { /*! * This class creates the vertices for an geodesic polyhedron in a 3D scene. 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..6a0f84f1 100644 --- a/mplot/GraphVisual.h +++ b/mplot/GraphVisual.h @@ -4,37 +4,46 @@ * \author Seb James * \date 2020 */ -#pragma once +module; #include #include #include +#include #include #include #include #include #include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mplot + +export module mplot.graphvisual; + +import mplot.graphing; +export import mplot.graphstyles; +export import mplot.datasetstyle; + +import sm.scale; +import sm.range; +export import sm.vec; +export import sm.vvec; +import sm.quaternion; +import sm.histo; +import sm.grid; + + +import mplot.tools; +import mplot.colour; +import mplot.gl.version; +import mplot.visualmodel; +import mplot.colourmap; +import mplot.visualtextmodel; +import mplot.visualfont; + +export namespace mplot { /*! * A VisualModel for showing a 2D graph. 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/GridVisual.h b/mplot/GridVisual.h index 1c6056a2..20bdff53 100644 --- a/mplot/GridVisual.h +++ b/mplot/GridVisual.h @@ -1,18 +1,24 @@ -#pragma once +module; +#include #include #include #include #include -#include -#include -#include +export module mplot.gridvisual; -#include -#include +import sm.grid; +export import sm.vec; +import sm.flags; -namespace mplot +import mplot.gl.version; +import mplot.colourmap; +import mplot.colour; +export import mplot.visualmodel; +export import mplot.visualdatamodel; + +export namespace mplot { /*! * How to visualize a grid. You could draw a triangle map with vertices at the centres of the 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..8d7270aa 100644 --- a/mplot/HexGridVisual.h +++ b/mplot/HexGridVisual.h @@ -3,14 +3,15 @@ #include #include #include -#include -#include +import sm.vec; +import sm.vvec; #include -#include -#include -#include -#include -#include +import sm.scale; + +import mplot.gl.version; +import mplot.tools; +import mplot.visualdatamodel; +import mplot.colourmap; /* * Macros for testing neighbours. The step along for neighbours on the 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..afe1d8d2 100644 --- a/mplot/InstancedScatterVisual.h +++ b/mplot/InstancedScatterVisual.h @@ -4,17 +4,21 @@ * \author Seb James * \date 2025 */ -#pragma once +module; #include #include #include -#include -#include -#include -#include -namespace mplot +export module mplot.instancedscattervisual; + +export import sm.vec; +export import mplot.graphstyles; +export import mplot.colour; +export import mplot.visualmodel; +import mplot.tools; + +export namespace mplot { template class InstancedScatterVisual : public VisualModel 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/NavMesh.h b/mplot/NavMesh.h index 5a103745..4a9fe28d 100644 --- a/mplot/NavMesh.h +++ b/mplot/NavMesh.h @@ -7,27 +7,31 @@ * \author Seb James * \date October 2025 */ - -#pragma once +module; #include +#include +#include #include #include #include #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; +import sm.mat; +import sm.geometry; +import sm.util; -namespace mplot +export namespace mplot { namespace mesh { diff --git a/mplot/NormalsVisual.h b/mplot/NormalsVisual.h index 59356caf..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 -#include -#include -#include -#include -#include +#include -namespace mplot +export module mplot.normalsvisual; + +export import mplot.visualmodel; +export import sm.vec; +import sm.mat; +import sm.flags; + +export namespace mplot { enum class normalsvisual_flags : uint32_t { 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/RodVisual.h b/mplot/RodVisual.h index c15a2738..8dc3bb70 100644 --- a/mplot/RodVisual.h +++ b/mplot/RodVisual.h @@ -1,11 +1,16 @@ -#pragma once +module; -#include -#include -#include +#include #include +#include + +export module mplot.rodvisual; + +import sm.vec; +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 @@ -49,6 +54,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(); @@ -62,7 +68,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/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..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 -#include -#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/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/TextFeatures.h b/mplot/TextFeatures.h index e8d73664..5a5b0595 100644 --- a/mplot/TextFeatures.h +++ b/mplot/TextFeatures.h @@ -1,10 +1,13 @@ -#pragma once +module; #include -#include -#include -namespace mplot +export module mplot.textfeatures; + +import mplot.visualfont; +import mplot.colour; + +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..6211b429 100644 --- a/mplot/TextGeometry.h +++ b/mplot/TextGeometry.h @@ -1,6 +1,6 @@ -#pragma once +export module mplot.textgeometry; -namespace mplot +export namespace mplot { /*! * A class containing information about a text string, as it would be displayed on 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..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 -#include -#include -#include -#include -namespace mplot +export module mplot.vectorvisual; + +import sm.vec; +import mplot.visualmodel; +import mplot.colourmap; + +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/VerticesVisual.h b/mplot/VerticesVisual.h index 34513f36..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 -#include -#include -#include +export module mplot.verticesvisual; -#include +import sm.vec; +import sm.vvec; +import sm.mat; -namespace mplot +export import mplot.visualmodel; + +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 74c47e73..d6e31517 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 @@ -24,17 +24,18 @@ #include #include +#include -namespace mplot -{ - // With mplot::Visual, we use a GLFW window which is owned by mplot::Visual. - using win_t = GLFWwindow; -} +export module mplot.visual; + +export import mplot.gl.version; +export import mplot.win_t; -#include -#include +import mplot.visualresources; +export import mplot.visualglfw; +export import mplot.visualownable; -namespace mplot +export namespace mplot { /*! * Visual 'scene' class @@ -69,11 +70,8 @@ namespace mplot this->options.set (visual_options::versionStdout, _version_stdout); this->init_resources(); - this->init_gl(); - - // Special tasks: re-bind coordArrows and title text - this->bindextra (this->coordArrows); - this->bindextra (this->textModel); + 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 } //! Deconstructor destroys GLFW/Qt window and deregisters access to VisualResources @@ -95,8 +93,10 @@ 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(); + mplot::VisualResources::i().freetype_init (this->visual_id, this->glfn); this->releaseContext(); } @@ -158,28 +158,6 @@ namespace mplot //! Obtain the window pointer win_t* getWindow() { return this->window; } - /*! - * 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; - } - /* * A note on setContext() in keepOpen/poll/waitevents/wait: * diff --git a/mplot/VisualBase.h b/mplot/VisualBase.h deleted file mode 100644 index b9ba746d..00000000 --- a/mplot/VisualBase.h +++ /dev/null @@ -1,1739 +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 - */ -#pragma once - -#include -#include -#include -#include -#include -#include -#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 -#include - -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 - }; - -#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 - - /*! - * 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(); - 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()) { - - // 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(); - } - } - - //! 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; - - //! 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 }; - - //! 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 - */ - - //! 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()) { - - 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/VisualCommon.h b/mplot/VisualCommon.h index 38d1dd07..4d48931c 100644 --- a/mplot/VisualCommon.h +++ b/mplot/VisualCommon.h @@ -1,25 +1,40 @@ -#pragma once - /* * Common code for GL functionality in mathplot programs. * * Author: Seb James. */ +module; +#include #include #include #include #include #include -#include -#include -#include -#include -#include -#include -namespace mplot +export module mplot.visualcommon; + +import sm.vec; +import sm.range; +import sm.vvec; +import sm.mat; +import mplot.colour; +import mplot.tools; + +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 { @@ -45,7 +60,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/VisualDataModel.h b/mplot/VisualDataModel.h index fe3d7abd..5e9a63b5 100644 --- a/mplot/VisualDataModel.h +++ b/mplot/VisualDataModel.h @@ -1,18 +1,23 @@ /*! * VisualModels which have data. */ -#pragma once +module; #include #include -#include -#include -#include -#include -#include -#include - -namespace mplot + +export module mplot.visualdatamodel; + +import sm.vec; +import sm.vvec; +import sm.scale; +import sm.centroid; + +export import mplot.visualmodel; +import mplot.colourmap; +import mplot.gl.version; + +export namespace mplot { //! VisualDataModel implementation base class containing common functionality - all the //! sm::scale objects and methods. 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/VisualFace.h b/mplot/VisualFace.h index b0ce482e..fe43db11 100644 --- a/mplot/VisualFace.h +++ b/mplot/VisualFace.h @@ -1,30 +1,51 @@ /*! * \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 */ - -#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 #endif -namespace mplot::visgl +// FreeType for text rendering +#include +#include FT_FREETYPE_H + +#include +#include +#include +#include + +#include + +/* + * Module starts here + */ + +export module mplot.visualface; + +import mplot.visualcommon; +import mplot.visualfont; +import mplot.textfeatures; +import mplot.tools; + +import sm.vec; + +export namespace mplot::visgl { - struct VisualFace : public mplot::visgl::VisualFaceBase + struct 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, @@ -41,6 +62,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! @@ -81,7 +104,8 @@ 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 }; @@ -99,6 +123,248 @@ namespace mplot::visgl FT_Done_Face (this->face); } - ~VisualFace() {} + ~VisualFace () {} + + //! 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) + { + constexpr bool debug_visualface = false; + + 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) + { + constexpr bool debug_visualface = false; + 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/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(); } diff --git a/mplot/VisualFaceBase.h b/mplot/VisualFaceBase.h deleted file mode 100644 index b1f11841..00000000 --- a/mplot/VisualFaceBase.h +++ /dev/null @@ -1,413 +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 - */ - -#pragma once - -#include -#include -#include -#include - -#include -#include // for visgl::CharInfo -#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 - -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 9d620373..acbcf100 100644 --- a/mplot/VisualFont.h +++ b/mplot/VisualFont.h @@ -1,10 +1,10 @@ -#pragma once +export module mplot.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..550d85c0 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 @@ -17,7 +16,11 @@ #include #include -namespace mplot +export module mplot.visualglfw; + +import mplot.gl.version; + +export namespace mplot { //! Singleton resource class for mplot::Visual scenes. template diff --git a/mplot/VisualModel.h b/mplot/VisualModel.h index e2f8d55a..6874d128 100644 --- a/mplot/VisualModel.h +++ b/mplot/VisualModel.h @@ -1,35 +1,71 @@ /*! * \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 */ - -#pragma once +module; #if defined __gl3_h_ || defined __gl_h_ // GL headers have been externally included #else -# error "GL headers should have been included already" +# include #endif +#include #include - -#include - -#include -#include -#include - -namespace mplot +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +export module mplot.visualmodel; + +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; +import sm.base64; + +// Need to import common here +export import mplot.gl.version; +export import mplot.visualcommon; +export import mplot.visualresources; +export import mplot.visualtextmodel; +export import mplot.colour; +import mplot.gl.util; +import mplot.tools; + +export import :navmesh; + +export namespace mplot { - //! Forward declaration of base classes - template class VisualBase; - template class VisualOwnable; + union float_bytes // for gltf output + { + float f; + uint8_t bytes[sizeof(float)]; + }; /*! * An OpenGL model class @@ -43,16 +79,14 @@ 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 @@ -60,114 +94,41 @@ namespace mplot // Explicitly clear owned VisualTextModels this->texts.clear(); if (this->vbos != nullptr) { - GladGLContext* _glfn = this->get_glfn (this->parentVis); - _glfn->DeleteBuffers (this->numVBO, this->vbos.get()); - _glfn->DeleteVertexArrays (1, &this->vao); - } - } - - /*! - * 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; - } - - 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 - { - 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]); + GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->parentVis); + if (glfn) { + glfn->DeleteBuffers (this->numVBO, this->vbos.get()); + glfn->DeleteVertexArrays (1, &this->vao); + } } - this->instparam_count = colour.size(); - - this->instanced_needs_update (this->parentVis); } //! Common code to call after the vertices have been set up. GL has to have been initialised. - void postVertexInit() final + void postVertexInit() { - GladGLContext* _glfn = this->get_glfn (this->parentVis); + 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->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->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" @@ -177,13 +138,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"); } @@ -194,20 +155,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" @@ -217,158 +178,15 @@ 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); } //! 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 - { - GladGLContext* _glfn = this->get_glfn(this->parentVis); - 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(); } - GladGLContext* _glfn = this->get_glfn(this->parentVis); - // 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; - - GladGLContext* _glfn = this->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)); - - 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); - } - - + virtual void initializeVertices() {}; /*! * Helper to make a VisualTextModel and bind it ready for use. * @@ -384,8 +202,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); + tmup->set_parent (this->parentVis); return tmup; } @@ -399,11 +218,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); @@ -419,7 +238,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(); } @@ -434,11 +253,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); @@ -455,18 +274,18 @@ 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(); } - 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++; } @@ -496,28 +315,3356 @@ namespace mplot while (ti != this->texts.end()) { (*ti)->addViewRotation (r); ti++; } } - //! Get the GladGLContext function pointer - std::function*)> get_glfn; + //! Process vertices and find the bounding box + void update_bb() + { + if (this->flags.test (vm_bools::compute_bb) == false) { return; } - protected: + 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(); + } - //! A vector of pointers to text models that should be rendered. - std::vector>> texts; + /*! + * Re-initialize the buffers. Client code might have appended to + * vertexPositions/Colors/Normals and indices before calling this method. + */ + void reinit_buffers() + { + GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->parentVis); - //! 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 + 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 + + 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() { - std::size_t sz = dat.size() * sizeof(float); + mplot::VisualResources::i().setContext (this->parentVis); + if (this->flags.test (vm_bools::postVertexInitRequired) == true) { this->postVertexInit(); } + GladGLContext* glfn = mplot::VisualResources::i().get_glfn (this->parentVis); + // 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() + { + mplot::VisualResources::i().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() + { + mplot::VisualResources::i().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() }; + } - GladGLContext* _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); + // 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() + { + mplot::VisualResources::i().setContext (this->parentVis); // need context? yes for text. + 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. + mplot::VisualResources::i().releaseContext(); + } + + 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; + + 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); + 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); + } 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 (gprog, static_cast("alpha")); + if (loc_a != -1) { glfn->Uniform1f (loc_a, this->alpha); } + + // The scene-view matrix + 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 (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 (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; + std::cout << "VisualModel::render: model viewmatrix:\n" << this->viewmatrix << std::endl; + } + + // Draw the triangles + 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); + } 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); } + + //! 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); + } + + //! 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); + } + + //! 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); + } + + //! 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 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; + + //! 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 (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 + 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) { + mplot::VisualResources::i().insert_instparam_data (this->instance_start + i, colour[i], alpha[i], scale[i]); + } + this->instparam_count = colour.size(); + + mplot::VisualResources::i().instanced_needs_update (this->parentVis); + } + + //! Setter for the parent ID, parentVis + void set_parent (const uint32_t _vis) + { + if (this->parentVis == std::numeric_limits::max()) { 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. + 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) + { + std::size_t sz = dat.size() * sizeof(float); + + if (this->parentVis == std::numeric_limits::max()) { + throw std::runtime_error ("parentVis is unset"); + } + 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); + 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]); + } + + 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 2dfcdefd..00000000 --- a/mplot/VisualModelBase.h +++ /dev/null @@ -1,3321 +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 -# error "GL headers should have been included already" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace mplot -{ - union float_bytes - { - 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; - - /*! - * 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); - 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; - } - - //! 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 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; - - /*! - * 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; - - //! 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 446310c2..fc4880c5 100644 --- a/mplot/VisualOwnable.h +++ b/mplot/VisualOwnable.h @@ -14,31 +14,166 @@ * \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. -#else -// Include GLAD header -# define GLAD_GL_IMPLEMENTATION -# 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 +#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 +#define LODEPNG_NO_COMPILE_DECODER 1 +#define LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS 1 +#include + +#include + +export module mplot.visualownable; -namespace mplot +export import mplot.visualmodel; +export import mplot.win_t; +export import mplot.visualcommon; +import mplot.visualresources; +export import mplot.visualtextmodel; +export import mplot.textgeometry; +export import mplot.textfeatures; +import mplot.coordarrows; +export import mplot.gl.version; +import mplot.gl.util; +import mplot.tools; + +export import sm.vec; +export import sm.flags; +import sm.quaternion; +import sm.mat; + +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 + + //! 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, (gone to VisualResources) + //! 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 + * 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 @@ -47,7 +182,7 @@ 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: /*! @@ -55,7 +190,11 @@ 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 @@ -63,14 +202,17 @@ 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(); } + ~VisualOwnable() {} + //! Deconstruct gl memory/context void deconstructCommon() { @@ -78,14 +220,13 @@ 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); } + 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); this->shaders.gprog = 0; - this->active_gprog = mplot::visgl::graphics_shader_type::none; } if (this->shaders.tprog) { this->glfn->DeleteProgram (this->shaders.tprog); @@ -94,17 +235,18 @@ 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() final + // 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) { - // 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); + this->window = ctx; + this->init_resources(); + this->init_gl(); } - public: // 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. @@ -112,25 +254,123 @@ 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->window); + mplot::VisualResources::i().freetype_init (this->visual_id, this->glfn); + } + + /*! + * 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); + 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)); + 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); + 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)); + 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(); + 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); } } - //! GLAD OpenGL function context pointer + 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::VisualOwnable* _v) { _v->render(); }; + + //! 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); @@ -143,20 +383,20 @@ 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); @@ -166,18 +406,10 @@ namespace mplot } //! Render the scene - void render() noexcept final + void render() noexcept { 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); @@ -241,14 +473,9 @@ 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(); @@ -284,11 +511,22 @@ namespace mplot } } - //! Glad MX specific callback - static GladGLContext* get_glfn (mplot::VisualBase* _v) + //! Compute a translation vector for text position, using Visual::text_z. + sm::vec textPosition (const sm::vec p0_coord) { - return reinterpret_cast*>(_v)->glfn; - }; + // 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; + } protected: // GLAD specific gl context creation/freeing. GladGLContext is a struct containing @@ -319,21 +557,6 @@ namespace mplot } } - // 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; - } - //! 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, @@ -343,7 +566,7 @@ 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); + tmup->set_parent (this->visual_id); if (tfeatures.centre_horz == true) { mplot::TextGeometry tg = tmup->getTextGeometry(_text); sm::vec centred_locn = _toffset; @@ -369,7 +592,7 @@ 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); + tmup->set_parent (this->visual_id); if (tfeatures.centre_horz == true) { mplot::TextGeometry tg = tmup->getTextGeometry(_text); sm::vec centred_locn = _toffset; @@ -384,29 +607,6 @@ namespace mplot return tm->getTextGeometry(); } - static unsigned int init_instance_data (mplot::VisualBase* _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); - 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(); - } - 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 @@ -430,7 +630,7 @@ 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 = { @@ -438,6 +638,7 @@ 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); @@ -450,31 +651,18 @@ 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); + 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)... 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 mplot::TextFeatures title_tf(0.035f, 64); this->textModel = std::make_unique> (title_tf); - this->bindmodel (this->textModel); + this->textModel->set_parent (this->visual_id); this->textModel->setSceneTranslation ({0.0f, 0.0f, 0.0f}); this->textModel->setupText (this->title); @@ -485,6 +673,1387 @@ 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; // 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 + std::vector text_shader_progs; + + //! 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()? 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. + */ + + 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; + } + + uint32_t get_id() const { return this->visual_id; } + + 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; // tuple + std::multimap, mplot::VisualModel*> > possible_centres; // pair + 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() } }); // tuple + possible_centres.insert ({ pdist, std::make_pair (tr_bb_centre, (*vmi).get()) }); // pair + } + } + ++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; // 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 + } // 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 0fb3d905..fe4d2613 100644 --- a/mplot/VisualResources.h +++ b/mplot/VisualResources.h @@ -4,43 +4,70 @@ * 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 */ +module; -#pragma once +// Include GLAD header +#include -#include -#include -#include -#include -#include -#include +// Probably DO want to separate all things GLFW into VisualGlfw. +#ifndef _glfw3_h_ +# define GLFW_INCLUDE_NONE +# include +#endif -#include -#include -#include +// FreeType for text rendering +#include +#include FT_FREETYPE_H + +#include +#include +#include +#include #include -namespace mplot -{ - // Pointers to mplot::VisualBase are used to index font faces - template - class VisualBase; +export module mplot.visualresources; - //! Singleton resource class for mplot::Visual scenes. +import mplot.visualcommon; +import mplot.visualface; +import mplot.visualfont; +import mplot.textfeatures; +import mplot.win_t; +import mplot.gl.version; +import mplot.gl.util; +import sm.vec; + +export namespace mplot +{ + //! 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*>, + //! 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. Keyed by the 'visual_id' an ID of the Visual instance. + std::map freetypes; + public: VisualResources(const VisualResources&) = delete; VisualResources& operator=(const VisualResources &) = delete; @@ -53,7 +80,7 @@ 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 { @@ -72,6 +99,20 @@ namespace mplot } } + //! When a mplot::Visual goes out of scope, its freetype library instance should be + //! deinitialized. + void freetype_deinit (uint32_t _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); + 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() @@ -81,12 +122,12 @@ 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. 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); @@ -100,30 +141,143 @@ namespace mplot } mplot::visgl::VisualFace* getVisualFace (const mplot::TextFeatures& tf, - mplot::VisualBase* _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 (mplot::VisualBase* _vis) final + 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 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++; + 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; + std::cout << "Registered Visual ID " << visual_id << std::endl; + return visual_id; + } + + // 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 (const uint32_t visual_id) noexcept + { + 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); } @@ -172,12 +326,35 @@ 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 aec053ab..00000000 --- a/mplot/VisualResourcesBase.h +++ /dev/null @@ -1,97 +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 - */ - -#pragma once - -#include -#include -#include -// FreeType for text rendering -#include -#include FT_FREETYPE_H - -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 c0adcea5..0666ac62 100644 --- a/mplot/VisualTextModel.h +++ b/mplot/VisualTextModel.h @@ -5,64 +5,78 @@ * 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 */ - -#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 #endif -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include -namespace mplot -{ - //! Forward declaration of a VisualBase class - template class VisualBase; +#include + +#include + +export module mplot.visualtextmodel; + +import mplot.visualresources; +import mplot.visualcommon; +export import mplot.textgeometry; +export import mplot.textfeatures; +import mplot.visualface; +import mplot.colour; +import mplot.gl.version; +import mplot.gl.util; + +import sm.quaternion; +import sm.mat; +import sm.vec; +export namespace mplot +{ /*! - * 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() { 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); } } //! Render the VisualTextModel - void render() final + void render() { 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); @@ -103,19 +117,20 @@ namespace mplot } //! 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; - 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. 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; @@ -127,14 +142,14 @@ namespace mplot } //! Return the geometry for the stored txt - mplot::TextGeometry getTextGeometry() final + mplot::TextGeometry getTextGeometry() { 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++) { @@ -148,10 +163,6 @@ 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}) @@ -177,14 +188,15 @@ 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) { + 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; @@ -226,7 +238,7 @@ 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] @@ -258,9 +270,9 @@ 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); + 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- @@ -294,24 +306,256 @@ namespace mplot _glfn->BindVertexArray(0); // carefully unbind } - public: - //! Get the GladGLContext function pointer - std::function*)> get_glfn; - - 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); + 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) + { + 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 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. The mplot::Visual ID to which I belong. max means unset. + uint32_t parentVis = std::numeric_limits::max(); + + //! Setter for the parent pointer, parentVis + void set_parent (const uint32_t _vis) + { + if (this->parentVis != std::numeric_limits::max()) { + 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; + + //! 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 a834faac..00000000 --- a/mplot/VisualTextModelBase.h +++ /dev/null @@ -1,321 +0,0 @@ -/*! - * \file - * - * Declares a base class for VisualTextModels. - * - * \author Seb James - * \date March 2025 - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -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 - GLuint ib = (GLuint)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 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 - 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; - } - - 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 - GLuint vao = 0; - //! Single vbo to use as in example - GLuint 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 (GLuint& 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 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/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/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 = {{ diff --git a/mplot/compoundray/EyeVisual.h b/mplot/compoundray/EyeVisual.h index bcea798a..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 -#include -#include -#include -#include -#include -#include -#include #include -namespace mplot::compoundray +export module mplot.compoundray.eyevisual; + +export import sm.vec; +import sm.mat; +import sm.range; +import sm.geometry; +import sm.centroid; + +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/compoundray/interop.h b/mplot/compoundray/interop.h index c97fc8c4..98a6ab78 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,20 @@ #include #include -// maths and mathplot includes -#include -#include -#include -#include +export module mplot.compoundray.interop; + +// maths and mathplot imports +import sm.vec; +import sm.vvec; +import sm.mat; + +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) @@ -145,7 +149,7 @@ 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(); 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; 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/loadshaders_mx.h b/mplot/gl/loadshaders_mx.h index a2ec95e7..6d2cef85 100644 --- a/mplot/gl/loadshaders_mx.h +++ b/mplot/gl/loadshaders_mx.h @@ -6,23 +6,25 @@ #include -#include +#include #include #include #include #include +import mplot.tools; + 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 +35,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 +66,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 +101,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..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 @@ -39,21 +45,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 +73,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/gl/ssbo_mx.h b/mplot/gl/ssbo_mx.h index 814a5caa..262c1dfc 100644 --- a/mplot/gl/ssbo_mx.h +++ b/mplot/gl/ssbo_mx.h @@ -10,10 +10,11 @@ */ #include -#include -#include -#include -#include + +import sm.vec; +import sm.vvec; +import sm.range; +import mplot.gl.util; namespace mplot::gl { 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/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/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"; diff --git a/mplot/glad/CMakeLists.txt b/mplot/glad/CMakeLists.txt index fb65bb6d..7966b48b 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 STATIC 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_ */ diff --git a/mplot/graphing.h b/mplot/graphing.h index 5c3acadc..ba5d2ba0 100644 --- a/mplot/graphing.h +++ b/mplot/graphing.h @@ -5,8 +5,7 @@ * Seb James * March 2025 */ - -#pragma once +module; #include #include @@ -21,16 +20,20 @@ # include #endif -#include -#include -#include +#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); @@ -98,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 = {}; @@ -192,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); @@ -202,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 diff --git a/mplot/jcvoronoi/jc_voronoi.h b/mplot/jcvoronoi/jc_voronoi.h index ba317437..b6ad077c 100644 --- a/mplot/jcvoronoi/jc_voronoi.h +++ b/mplot/jcvoronoi/jc_voronoi.h @@ -19,11 +19,13 @@ #include #include // assert() #include // uintptr_t etc +#include // std::memset +#include #include #include -#include -#include -#include +import sm.vec; +import sm.geometry; +import sm.winder; #ifndef JCV_EDGE_INTERSECT_THRESHOLD // Fix for Issue #40 @@ -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*)); 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 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 { 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); } }; diff --git a/mplot/win_t.h b/mplot/win_t.h new file mode 100644 index 00000000..c5343ea5 --- /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.win_t; + +export namespace mplot +{ + // With mplot::Visual, we use a GLFW window which is owned by mplot::Visual. + using win_t = GLFWwindow; +}