[
  {
    "path": ".clang-format",
    "content": "BasedOnStyle: LLVM\nUseTab: Never\nTabWidth: 4\nIndentWidth: 4\nColumnLimit: 80\nAlwaysBreakTemplateDeclarations: Yes\nBinPackArguments: false\nBinPackParameters: false\n"
  },
  {
    "path": ".gitignore",
    "content": ".vscode\n/build*/\n/dist/\n/data\n/radfoam/\n/*output*\n\n*.egg-info\n__pycache__\n/*nsight\n*.mp4b\n*ipynb\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"external/submodules/glfw\"]\n\tpath = external/submodules/glfw\n\turl = https://github.com/glfw/glfw\n[submodule \"external/submodules/eigen\"]\n\tpath = external/submodules/eigen\n\turl = https://gitlab.com/libeigen/eigen.git\n[submodule \"external/submodules/imgui\"]\n\tpath = external/submodules/imgui\n\turl = https://github.com/ocornut/imgui\n[submodule \"external/submodules/atomic_queue\"]\n\tpath = external/submodules/atomic_queue\n\turl = https://github.com/max0x7ba/atomic_queue\n[submodule \"external/submodules/mesa\"]\n\tpath = external/submodules/mesa\n\turl = https://gitlab.freedesktop.org/mesa/mesa.git\n[submodule \"external/submodules/tbb\"]\n\tpath = external/submodules/tbb\n\turl = https://github.com/uxlfoundation/oneTBB\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.27)\nproject(RadFoam VERSION 1.0.0)\n\ncmake_policy(SET CMP0060 NEW)\n\nenable_language(CUDA)\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CUDA_STANDARD 17)\nset(CMAKE_C_EXTENSIONS OFF)\nset(CMAKE_CXX_EXTENSIONS OFF)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_POSITION_INDEPENDENT_CODE ON)\n\nset(GPU_DEBUG\n    ON\n    CACHE BOOL \"Enable GPU debug features\")\nadd_definitions(-DGPU_DEBUG=$<BOOL:${GPU_DEBUG}>)\nif(NOT CMAKE_BUILD_TYPE)\n  set(CMAKE_BUILD_TYPE\n      \"Release\"\n      CACHE STRING \"Build type\")\nendif()\n\nset(CMAKE_MODULE_PATH \"${CMAKE_SOURCE_DIR}/cmake\" ${CMAKE_MODULE_PATH})\nlist(APPEND CMAKE_PREFIX_PATH \"${CMAKE_SOURCE_DIR}/external\"\n     \"${CMAKE_SOURCE_DIR}/external/submodules\")\n\nfind_package(\n  Python3\n  COMPONENTS Interpreter Development.Module\n  REQUIRED)\n\nfind_package(pybind11 REQUIRED)\n\nif(NOT Torch_DIR)\n  set(Torch_DIR ${Python3_SITELIB}/torch/share/cmake/Torch)\nendif()\n\nfind_package(Torch REQUIRED)\nfind_library(TORCH_PYTHON_LIBRARY torch_python PATH\n             \"${TORCH_INSTALL_PREFIX}/lib\")\n\nadd_subdirectory(external)\ninclude_directories(${RADFOAM_EXTERNAL_INCLUDES})\n\nif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)\n  set(CMAKE_INSTALL_PREFIX\n      \"${CMAKE_SOURCE_DIR}/radfoam\"\n      CACHE PATH \"...\" FORCE)\nendif()\n\nset(RADFOAM_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})\n\nadd_subdirectory(src)\nadd_subdirectory(torch_bindings)\n"
  },
  {
    "path": "LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2025 The Radiant Foam Authors\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "# Radiant Foam: Real-Time Differentiable Ray Tracing\n\n![](teaser.jpg)\n\n## Shrisudhan Govindarajan, Daniel Rebain, Kwang Moo Yi, Andrea Tagliasacchi\n\nThis repository contains the official implementation of [Radiant Foam: Real-Time Differentiable Ray Tracing](https://radfoam.github.io).\n\nThe code includes scripts for training and evaluation, as well as a real-time viewer that can be used to visualize trained models, or optionally to observe the progression of models as they train. Everything in this repository is non-final and subject to change as the project is still being actively developed. **We encourage anyone citing our results to do as RadFoam (vx), where x is the version specified for those metrics in the paper or tagged to a commit on GitHub.** This should hopefully reduce confusion.\n\nWarning: this is an organic, free-range research codebase, and should be treated with the appropriate care when integrating it into any other software.\n\n## Known issues\n - GPU memory usage can be high for scenes with many points. You may need to reduce the `final_points` setting to train outdoor scenes on a 24GB GPU. This will hopefully be improved the future.\n - Best PSNR is acheived with the default softplus density activation, but also it causes an increase in volumetric artifacts. Using exponential activation may result in qualitatively better renders. We are planning to add configuration options for this.\n - The Delaunay triangulation is not perfectly robust, and relies on random perturbation of points and iterative retries to attempt to recover from failures. Training may stall for long periods when this occurs.\n\n## Getting started\n\nStart by cloning the repository and submodules:\n\n    git clone --recursive https://github.com/theialab/radfoam\n\nYou will need a Linux environment with Python 3.10 or newer, as well as version 12.x of the [CUDA Toolkit](https://developer.nvidia.com/cuda-downloads) and a CUDA-compatible GPU of Compute Capability 7.0 or higher. Please ensure that your installation method for CUDA places `nvcc` in your `PATH`. The following instructions were tested with Ubuntu 24.04.\n\nAfter installing the CUDA Toolkit and initializing your python virtual environment, install PyTorch 2.3 or newer. For example, with CUDA 12.1:\n\n    pip install torch==2.3.0 torchvision==0.18.0 torchaudio==2.3.0 --index-url https://download.pytorch.org/whl/cu121\n\nFrom here, there are two options:\n\n### Option 1: build with `pip install`\n\nChoose this option if you want to run the code as-is, and do not need to make modifications to the CUDA/C++ code.\n\nSimply run `pip install .` in the repository root. This will build the CUDA kernels and install them along with the python bindings into your python environment. This may take some time to complete, but once finished, you should be able to run the code without further setup.\n\nOptionally if you want to install with the frozen version of required packages, you can do so by running `pip install -r requirements.txt` before running `pip install .`\n\n### Option 2: build with CMake\n\nChoose this option if you intend to modify the CUDA/C++ code. Using CMake directly will allow you to quickly recompile the kernels as needed.\n\nFirst install the Python dependencies:\n\n    pip install -r requirements.txt\n\n\nThen, create a `build` directory in the repository root and run the following commands from it to initialize CMake and build the bindings library:\n\n    cmake ..\n    make install\n\nThis will install to a local `radfoam` directory in the repository root. Recompilation can be performed by re-running `make install` in the build directory.\n\n### Training\n\nPlace the [Mip-NeRF 360](https://jonbarron.info/mipnerf360) and [Deep Blending](https://github.com/Phog/DeepBlending) datasets in `data/mipnerf360` and `data/db`.\n\nTraining can then be launched with:\n\n    python train.py -c configs/<config_file>.yaml\n\nWhere `<config_file>` is either one of the supplied files in the `configs` directory or your own.\nYou can optionally include the `--viewer` flag to train interactively, or use the `viewer.py` script to view saved checkpoints.\n\n### Evaluation\n\nThe standard test metrics can be computed with:\n\n    python test.py -c outputs/<checkpoint_directory>/config.yaml\n\nRendering speed can be computed with:\n\n    python benchmark.py -c outputs/<checkpoint_directory>/config.yaml\n\n### Checkpoints\n\nYou can find trained checkpoints, as well as COLMAP output for some scenes [here](https://drive.google.com/drive/folders/1o8ulZORogwjrfsz3E-QY3f-oPjVFrEVI?usp=drive_link).\n\n## BibTeX\n\n    @article{govindarajan2025radfoam,\n        author = {Govindarajan, Shrisudhan and Rebain, Daniel and Yi, Kwang Moo and Tagliasacchi, Andrea},\n        title = {Radiant Foam: Real-Time Differentiable Ray Tracing},\n        journal = {arXiv:2502.01157},\n        year = {2025},\n    }\n"
  },
  {
    "path": "benchmark.py",
    "content": "import os\nimport numpy as np\nfrom PIL import Image\nimport configargparse\nimport warnings\n\nwarnings.filterwarnings(\"ignore\")\n\nimport torch\n\nfrom data_loader import DataHandler\nfrom configs import *\nfrom radfoam_model.scene import RadFoamScene\nimport radfoam\n\n\nseed = 42\ntorch.random.manual_seed(seed)\nnp.random.seed(seed)\n\n\ndef benchmark(args, pipeline_args, model_args, optimizer_args, dataset_args):\n    checkpoint = args.config.replace(\"/config.yaml\", \"\")\n    os.makedirs(os.path.join(checkpoint, \"test\"), exist_ok=True)\n    device = torch.device(args.device)\n\n    test_data_handler = DataHandler(\n        dataset_args, rays_per_batch=0, device=device\n    )\n    test_data_handler.reload(\n        split=\"test\", downsample=min(dataset_args.downsample)\n    )\n\n    # Setting up model\n    model = RadFoamScene(\n        args=model_args, device=device, attr_dtype=torch.float16\n    )\n\n    model.load_pt(f\"{checkpoint}/model.pt\")\n\n    points, attributes, point_adjacency, point_adjacency_offsets = (\n        model.get_trace_data()\n    )\n    self_point_inds = torch.zeros_like(point_adjacency.long())\n    scatter_inds = point_adjacency_offsets[1:-1].long()\n    self_point_inds.scatter_add_(0, scatter_inds, torch.ones_like(scatter_inds))\n    self_point_inds = torch.cumsum(self_point_inds, dim=0)\n    self_points = points[self_point_inds]\n\n    adjacent_points = points[point_adjacency.long()]\n    adjacent_offsets = adjacent_points - self_points\n    adjacent_offsets = torch.cat(\n        [adjacent_offsets, torch.zeros_like(adjacent_offsets[:, :1])], dim=1\n    ).to(torch.half)\n\n    c2w = test_data_handler.c2ws\n    width, height = test_data_handler.img_wh\n    fy = test_data_handler.fy\n\n    cameras = []\n    positions = []\n\n    for i in range(c2w.shape[0]):\n        if i % 8 == 0:\n            position = c2w[i, :3, 3].contiguous()\n            fov = float(2 * np.arctan(height / (2 * fy)))\n\n            right = c2w[i, :3, 0].contiguous()\n            up = -c2w[i, :3, 1].contiguous()\n            forward = c2w[i, :3, 2].contiguous()\n\n            positions.append(position)\n\n            camera = {\n                \"position\": position,\n                \"forward\": forward,\n                \"right\": right,\n                \"up\": up,\n                \"fov\": fov,\n                \"width\": width,\n                \"height\": height,\n                \"model\": \"pinhole\",\n            }\n            cameras.append(camera)\n\n    n_frames = len(cameras)\n\n    positions = torch.stack(positions, dim=0).to(device)\n    start_points = radfoam.nn(points, model.aabb_tree, positions)\n\n    output = torch.zeros(\n        (n_frames, height, width), dtype=torch.uint32, device=device\n    )\n\n    torch.cuda.synchronize()\n\n    # warmup\n    for i in range(n_frames):\n        model.pipeline.trace_benchmark(\n            points,\n            attributes,\n            point_adjacency,\n            point_adjacency_offsets,\n            adjacent_offsets,\n            cameras[i],\n            start_points[i],\n            output[i],\n            weight_threshold=0.05,\n        )\n\n    torch.cuda.synchronize()\n    n_reps = 5\n    start_event = torch.cuda.Event(enable_timing=True)\n    start_event.record()\n\n    for _ in range(n_reps):\n        for i in range(n_frames):\n            model.pipeline.trace_benchmark(\n                points,\n                attributes,\n                point_adjacency,\n                point_adjacency_offsets,\n                adjacent_offsets,\n                cameras[i],\n                start_points[i],\n                output[i],\n                weight_threshold=0.05,\n            )\n\n    end_event = torch.cuda.Event(enable_timing=True)\n    end_event.record()\n\n    torch.cuda.synchronize()\n\n    total_time = start_event.elapsed_time(end_event)\n    framerate = n_reps * n_frames / (total_time / 1000.0)\n\n    print(f\"Total time: {total_time} ms\")\n    print(f\"FPS: {framerate}\")\n\n\ndef main():\n    parser = configargparse.ArgParser()\n\n    model_params = ModelParams(parser)\n    dataset_params = DatasetParams(parser)\n    pipeline_params = PipelineParams(parser)\n    optimization_params = OptimizationParams(parser)\n\n    # Add argument to specify a custom config file\n    parser.add_argument(\n        \"-c\", \"--config\", is_config_file=True, help=\"Path to config file\"\n    )\n\n    # Parse arguments\n    args = parser.parse_args()\n\n    benchmark(\n        args,\n        pipeline_params.extract(args),\n        model_params.extract(args),\n        optimization_params.extract(args),\n        dataset_params.extract(args),\n    )\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "configs/__init__.py",
    "content": "import configargparse\nimport os\nfrom argparse import Namespace\n\n\nclass GroupParams:\n    pass\n\n\nclass ParamGroup:\n    def __init__(\n        self, parser: configargparse.ArgParser, name: str, fill_none=False\n    ):\n        group = parser.add_argument_group(name)\n        for key, value in vars(self).items():\n            t = type(value)\n            value = value if not fill_none else None\n            if t == bool:\n                group.add_argument(\n                    \"--\" + key, default=value, action=\"store_true\"\n                )\n            elif t == list:\n                group.add_argument(\n                    \"--\" + key,\n                    nargs=\"+\",\n                    type=type(value[0]),\n                    default=value,\n                    help=f\"List of {type(value[0]).__name__}\",\n                )\n            else:\n                group.add_argument(\"--\" + key, default=value, type=t)\n\n    def extract(self, args):\n        group = GroupParams()\n        for arg in vars(args).items():\n            if arg[0] in vars(self):\n                setattr(group, arg[0], arg[1])\n        return group\n\n\nclass PipelineParams(ParamGroup):\n\n    def __init__(self, parser):\n        self.iterations = 20_000\n        self.densify_from = 2_000\n        self.densify_until = 11_000\n        self.densify_factor = 1.15\n        self.white_background = True\n        self.quantile_weight = 1e-4\n        self.experiment_name = \"\"\n        self.debug = False\n        self.viewer = False\n        super().__init__(parser, \"Setting Pipeline parameters\")\n\n\nclass ModelParams(ParamGroup):\n\n    def __init__(self, parser):\n        self.sh_degree = 3\n        self.init_points = 131_072\n        self.final_points = 2_097_152\n        self.activation_scale = 1.0\n        self.device = \"cuda\"\n        super().__init__(parser, \"Setting Model parameters\")\n\n\nclass OptimizationParams(ParamGroup):\n\n    def __init__(self, parser):\n        self.points_lr_init = 2e-4\n        self.points_lr_final = 5e-6\n        self.density_lr_init = 1e-1\n        self.density_lr_final = 1e-2\n        self.attributes_lr_init = 5e-3\n        self.attributes_lr_final = 5e-4\n        self.sh_factor = 0.1\n        self.freeze_points = 18_000\n        super().__init__(parser, \"Setting Optimization parameters\")\n\n\nclass DatasetParams(ParamGroup):\n\n    def __init__(self, parser):\n        self.dataset = \"colmap\"\n        self.data_path = \"data/mipnerf360\"\n        self.scene = \"bonsai\"\n        self.patch_based = False\n        self.downsample = [4, 2, 1]\n        self.downsample_iterations = [0, 150, 500]\n        super().__init__(parser, \"Setting Dataset parameters\")\n"
  },
  {
    "path": "configs/db.yaml",
    "content": "# Model Parameters\nsh_degree: 3\ninit_points: 131_072\nfinal_points: 3_145_728\nactivation_scale: 1\ndevice: cuda\n\n# Pipeline Parameters\niterations: 20_000\ndensify_from: 2_000\ndensify_until: 11_000\ndensify_factor: 1.15\nwhite_background: true\nquantile_weight: 0\nviewer: false                          # Flag to use viewer\ndebug: false                           # Flag to not use tensorboard\n\n# Optimization Parameters\npoints_lr_init: 2e-4\npoints_lr_final: 5e-6\ndensity_lr_init: 1e-1\ndensity_lr_final: 1e-2\nattributes_lr_init: 5e-3\nattributes_lr_final: 5e-4\nsh_factor: 0.01\nfreeze_points: 18_000                  # Points are frozen after this cycle\n\n# Dataset Parameters\ndataset: \"colmap\"\ndata_path: \"data/db\"\nscene: \"playroom\"\npatch_based: false\ndownsample: [2, 1]                     # Image downsample factors\ndownsample_iterations: [0, 2_000]\n"
  },
  {
    "path": "configs/mipnerf360_indoor.yaml",
    "content": "# Model Parameters\nsh_degree: 3\ninit_points: 131_072\nfinal_points: 2_097_152\nactivation_scale: 1\ndevice: cuda\n\n# Pipeline Parameters\niterations: 20_000\ndensify_from: 2_000\ndensify_until: 11_000\ndensify_factor: 1.15\nwhite_background: true\nquantile_weight: 1e-4\nviewer: false                          # Flag to use viewer\ndebug: false                           # Flag to not use tensorboard\n\n# Optimization Parameters\npoints_lr_init: 2e-4\npoints_lr_final: 5e-6\ndensity_lr_init: 1e-1\ndensity_lr_final: 1e-2\nattributes_lr_init: 5e-3\nattributes_lr_final: 5e-4\nsh_factor: 0.1\nfreeze_points: 18_000                  # Points are frozen after this cycle\n\n# Dataset Parameters\ndataset: \"colmap\"\ndata_path: \"data/mipnerf360\"\nscene: \"bonsai\"\npatch_based: false\ndownsample: [4, 2]                     # Image downsample factors\ndownsample_iterations: [0, 5_000]\n"
  },
  {
    "path": "configs/mipnerf360_outdoor.yaml",
    "content": "# Model Parameters\nsh_degree: 3\ninit_points: 131_072\nfinal_points: 4_194_304\nactivation_scale: 1\ndevice: cuda\n\n# Pipeline Parameters\niterations: 20_000\ndensify_from: 2_000\ndensify_until: 11_000\ndensify_factor: 1.15\nwhite_background: true\nquantile_weight: 1e-4\nviewer: false                          # Flag to use viewer\ndebug: false                           # Flag to not use tensorboard\n\n# Optimization Parameters\npoints_lr_init: 2e-4\npoints_lr_final: 5e-6\ndensity_lr_init: 1e-1\ndensity_lr_final: 1e-2\nattributes_lr_init: 5e-3\nattributes_lr_final: 5e-4\nsh_factor: 0.02\nfreeze_points: 18_000                  # Points are frozen after this cycle\n\n# Dataset Parameters\ndataset: \"colmap\"\ndata_path: \"data/mipnerf360\"\nscene: \"garden\"\npatch_based: false\ndownsample: [8, 4]                     # Image downsample factors\ndownsample_iterations: [0, 5_000]\n"
  },
  {
    "path": "data_loader/__init__.py",
    "content": "import os\n\nimport numpy as np\nimport einops\nimport torch\n\nimport radfoam\n\nfrom .colmap import COLMAPDataset\nfrom .blender import BlenderDataset\n\n\ndataset_dict = {\n    \"colmap\": COLMAPDataset,\n    \"blender\": BlenderDataset,\n}\n\n\ndef get_up(c2ws):\n    right = c2ws[:, :3, 0]\n    down = c2ws[:, :3, 1]\n    forward = c2ws[:, :3, 2]\n\n    A = torch.einsum(\"bi,bj->bij\", right, right).sum(dim=0)\n    A += torch.einsum(\"bi,bj->bij\", forward, forward).sum(dim=0) * 0.02\n\n    l, V = torch.linalg.eig(A)\n\n    min_idx = torch.argmin(l.real)\n    global_up = V[:, min_idx].real\n    global_up *= torch.einsum(\"bi,i->b\", -down, global_up).sum().sign()\n\n    return global_up\n\n\nclass DataHandler:\n    def __init__(self, dataset_args, rays_per_batch, device=\"cuda\"):\n        self.args = dataset_args\n        self.rays_per_batch = rays_per_batch\n        self.device = torch.device(device)\n        self.img_wh = None\n        self.patch_size = 8\n\n    def reload(self, split, downsample=None):\n        data_dir = os.path.join(self.args.data_path, self.args.scene)\n        dataset = dataset_dict[self.args.dataset]\n        if downsample is not None:\n            split_dataset = dataset(\n                data_dir, split=split, downsample=downsample\n            )\n        else:\n            split_dataset = dataset(data_dir, split=split)\n        self.img_wh = split_dataset.img_wh\n        self.fx = split_dataset.fx\n        self.fy = split_dataset.fy\n        self.c2ws = split_dataset.poses\n        self.rays, self.rgbs = split_dataset.all_rays, split_dataset.all_rgbs\n        self.alphas = getattr(\n            split_dataset, \"all_alphas\", torch.ones_like(self.rgbs[..., 0:1])\n        )\n\n        self.viewer_up = get_up(self.c2ws)\n        self.viewer_pos = self.c2ws[0, :3, 3]\n        self.viewer_forward = self.c2ws[0, :3, 2]\n\n        try:\n            self.points3D = split_dataset.points3D\n            self.points3D_colors = split_dataset.points3D_color\n        except:\n            self.points3D = None\n            self.points3D_colors = None\n\n        if split == \"train\":\n            if self.args.patch_based:\n                dw = self.img_wh[0] - (self.img_wh[0] % self.patch_size)\n                dh = self.img_wh[1] - (self.img_wh[1] % self.patch_size)\n                w_inds = np.linspace(0, self.img_wh[0] - 1, dw, dtype=int)\n                h_inds = np.linspace(0, self.img_wh[1] - 1, dh, dtype=int)\n\n                self.train_rays = self.rays[:, h_inds, :, :]\n                self.train_rays = self.train_rays[:, :, w_inds, :]\n                self.train_rgbs = self.rgbs[:, h_inds, :, :]\n                self.train_rgbs = self.train_rgbs[:, :, w_inds, :]\n\n                self.train_rays = einops.rearrange(\n                    self.train_rays,\n                    \"n (x ph) (y pw) r -> (n x y) ph pw r\",\n                    ph=self.patch_size,\n                    pw=self.patch_size,\n                )\n                self.train_rgbs = einops.rearrange(\n                    self.train_rgbs,\n                    \"n (x ph) (y pw) c -> (n x y) ph pw c\",\n                    ph=self.patch_size,\n                    pw=self.patch_size,\n                )\n\n                self.batch_size = self.rays_per_batch // (self.patch_size**2)\n            else:\n                self.train_rays = einops.rearrange(\n                    self.rays, \"n h w r -> (n h w) r\"\n                )\n                self.train_rgbs = einops.rearrange(\n                    self.rgbs, \"n h w c -> (n h w) c\"\n                )\n                self.train_alphas = einops.rearrange(\n                    self.alphas, \"n h w 1 -> (n h w) 1\"\n                )\n\n                self.batch_size = self.rays_per_batch\n\n    def get_iter(self):\n        ray_batch_fetcher = radfoam.BatchFetcher(\n            self.train_rays, self.batch_size, shuffle=True\n        )\n        rgb_batch_fetcher = radfoam.BatchFetcher(\n            self.train_rgbs, self.batch_size, shuffle=True\n        )\n        alpha_batch_fetcher = radfoam.BatchFetcher(\n            self.train_alphas, self.batch_size, shuffle=True\n        )\n\n        while True:\n            ray_batch = ray_batch_fetcher.next()\n            rgb_batch = rgb_batch_fetcher.next()\n            alpha_batch = alpha_batch_fetcher.next()\n\n            yield ray_batch, rgb_batch, alpha_batch\n"
  },
  {
    "path": "data_loader/blender.py",
    "content": "import os\nimport numpy as np\nfrom PIL import Image\nimport torch\nfrom torch.utils.data import Dataset\nimport json\nimport math\n\n\ndef get_ray_directions(H, W, focal, center=None):\n    x = np.arange(W, dtype=np.float32) + 0.5\n    y = np.arange(H, dtype=np.float32) + 0.5\n    x, y = np.meshgrid(x, y)\n    pix_coords = np.stack([x, y], axis=-1).reshape(-1, 2)\n    i, j = pix_coords[..., 0:1], pix_coords[..., 1:]\n\n    cent = center if center is not None else [W / 2, H / 2]\n    directions = np.concatenate(\n        [\n            (i - cent[0]) / focal[0],\n            (j - cent[1]) / focal[1],\n            np.ones_like(i),\n        ],\n        axis=-1,\n    )\n    ray_dirs = directions / np.linalg.norm(directions, axis=-1, keepdims=True)\n    return torch.tensor(ray_dirs, dtype=torch.float32)\n\n\nclass BlenderDataset(Dataset):\n    def __init__(self, datadir, split=\"train\", downsample=1):\n\n        self.root_dir = datadir\n        self.split = split\n        self.downsample = downsample\n\n        self.blender2opencv = np.array(\n            [[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]]\n        )\n        self.points3D = None\n        self.points3D_color = None\n\n        with open(\n            os.path.join(self.root_dir, f\"transforms_{self.split}.json\"), \"r\"\n        ) as f:\n            meta = json.load(f)\n        if \"w\" in meta and \"h\" in meta:\n            W, H = int(meta[\"w\"]), int(meta[\"h\"])\n        else:\n            W, H = 800, 800\n\n        self.img_wh = (int(W / self.downsample), int(H / self.downsample))\n        w, h = self.img_wh\n\n        focal = (\n            0.5 * w / math.tan(0.5 * meta[\"camera_angle_x\"])\n        )  # scaled focal length\n\n        self.fx, self.fy = focal, focal\n        self.intrinsics = torch.tensor(\n            [[focal, 0, w / 2], [0, focal, h / 2], [0, 0, 1]]\n        )\n\n        cam_ray_dirs = get_ray_directions(\n            h, w, [self.intrinsics[0, 0], self.intrinsics[1, 1]]\n        )\n\n        self.poses = []\n        self.cameras = []\n        self.all_rays = []\n        self.all_rgbs = []\n        self.all_alphas = []\n        for i, frame in enumerate(meta[\"frames\"]):\n            pose = np.array(frame[\"transform_matrix\"]) @ self.blender2opencv\n            c2w = torch.FloatTensor(pose)\n            self.poses.append(c2w)\n            world_ray_dirs = torch.einsum(\n                \"ij,kj->ik\",\n                cam_ray_dirs,\n                c2w[:3, :3],\n            )\n            world_ray_origins = c2w[:3, 3] + torch.zeros_like(cam_ray_dirs)\n            world_rays = torch.cat([world_ray_origins, world_ray_dirs], dim=-1)\n            world_rays = world_rays.reshape(self.img_wh[1], self.img_wh[0], 6)\n\n            img_path = os.path.join(self.root_dir, f\"{frame['file_path']}.png\")\n            img = Image.open(img_path)\n            if self.downsample != 1.0:\n                img = img.resize(self.img_wh, Image.LANCZOS)\n            img = img.convert(\"RGBA\")\n            rgbas = torch.tensor(np.array(img), dtype=torch.float32) / 255.0\n            rgbs = rgbas[..., :3] * rgbas[..., 3:4] + (\n                1 - rgbas[..., 3:4]\n            )  # white bg\n            img.close()\n\n            self.all_rays.append(world_rays)\n            self.all_rgbs.append(rgbs)\n            self.all_alphas.append(rgbas[..., -1:])\n\n        self.poses = torch.stack(self.poses)\n        self.all_rays = torch.stack(self.all_rays)\n        self.all_rgbs = torch.stack(self.all_rgbs)\n        self.all_alphas = torch.stack(self.all_alphas)\n\n    def __len__(self):\n        return len(self.all_rgbs)\n\n    def __getitem__(self, idx):\n\n        if self.split == \"train\":  # use data in the buffers\n            sample = {\n                \"rays\": self.all_rays[idx],\n                \"rgbs\": self.all_rgbs[idx],\n                \"alphas\": self.all_alphas[idx],\n            }\n\n        else:  # create data for each image separately\n\n            img = self.all_rgbs[idx]\n            rays = self.all_rays[idx]\n            alphas = self.all_alphas[idx]\n\n            sample = {\"rays\": rays, \"rgbs\": img, \"alphas\": alphas}\n        return sample\n\n\nif __name__ == \"__main__\":\n    pass\n"
  },
  {
    "path": "data_loader/colmap.py",
    "content": "import os\n\nimport numpy as np\nfrom PIL import Image\nfrom tqdm import tqdm\nimport torch\nimport pycolmap\n\n\ndef get_cam_ray_dirs(camera):\n    x = np.arange(camera.width, dtype=np.float32) + 0.5\n    y = np.arange(camera.height, dtype=np.float32) + 0.5\n    x, y = np.meshgrid(x, y)\n    pix_coords = np.stack([x, y], axis=-1).reshape(-1, 2)\n    ip_coords = camera.cam_from_img(pix_coords)\n    ip_coords = np.concatenate(\n        [ip_coords, np.ones_like(ip_coords[:, :1])], axis=-1\n    )\n    ray_dirs = ip_coords / np.linalg.norm(ip_coords, axis=-1, keepdims=True)\n    return torch.tensor(ray_dirs, dtype=torch.float32)\n\n\nclass COLMAPDataset:\n    def __init__(self, datadir, split, downsample):\n        assert downsample in [1, 2, 4, 8]\n\n        self.root_dir = datadir\n        self.colmap_dir = os.path.join(datadir, \"sparse/0/\")\n        self.split = split\n        self.downsample = downsample\n\n        if downsample == 1:\n            images_dir = os.path.join(datadir, \"images\")\n        else:\n            images_dir = os.path.join(datadir, f\"images_{downsample}\")\n\n        if not os.path.exists(images_dir):\n            raise ValueError(f\"Images directory {images_dir} not found\")\n\n        self.reconstruction = pycolmap.Reconstruction()\n        self.reconstruction.read(self.colmap_dir)\n\n        if len(self.reconstruction.cameras) > 1:\n            raise ValueError(\"Multiple cameras are not supported\")\n\n        names = sorted(im.name for im in self.reconstruction.images.values())\n        indices = np.arange(len(names))\n\n        if split == \"train\":\n            names = list(np.array(names)[indices % 8 != 0])\n        elif split == \"test\":\n            names = list(np.array(names)[indices % 8 == 0])\n        else:\n            raise ValueError(f\"Invalid split: {split}\")\n\n        names = list(str(name) for name in names)\n\n        im = Image.open(os.path.join(images_dir, names[0]))\n        self.img_wh = im.size\n        im.close()\n\n        self.camera = list(self.reconstruction.cameras.values())[0]\n        self.camera.rescale(self.img_wh[0], self.img_wh[1])\n\n        self.fx = self.camera.focal_length_x\n        self.fy = self.camera.focal_length_y\n\n        cam_ray_dirs = get_cam_ray_dirs(self.camera)\n\n        self.images = []\n        for name in names:\n            image = None\n            for image_id in self.reconstruction.images:\n                image = self.reconstruction.images[image_id]\n                if image.name == name:\n                    break\n\n            if image is None:\n                raise ValueError(\n                    f\"Image {name} not found in COLMAP reconstruction\"\n                )\n\n            self.images.append(image)\n\n        self.poses = []\n        self.all_rays = []\n        self.all_rgbs = []\n        for image in tqdm(self.images):\n            c2w = torch.tensor(\n                image.cam_from_world.inverse().matrix(), dtype=torch.float32\n            )\n            self.poses.append(c2w)\n            world_ray_dirs = torch.einsum(\n                \"ij,kj->ik\",\n                cam_ray_dirs,\n                c2w[:, :3],\n            )\n            world_ray_origins = c2w[:, 3] + torch.zeros_like(cam_ray_dirs)\n            world_rays = torch.cat([world_ray_origins, world_ray_dirs], dim=-1)\n            world_rays = world_rays.reshape(self.img_wh[1], self.img_wh[0], 6)\n\n            im = Image.open(os.path.join(images_dir, image.name))\n            im = im.convert(\"RGB\")\n            rgbs = torch.tensor(np.array(im), dtype=torch.float32) / 255.0\n            im.close()\n\n            self.all_rays.append(world_rays)\n            self.all_rgbs.append(rgbs)\n\n        self.poses = torch.stack(self.poses)\n        self.all_rays = torch.stack(self.all_rays)\n        self.all_rgbs = torch.stack(self.all_rgbs)\n\n        self.points3D = []\n        self.points3D_color = []\n        for point in self.reconstruction.points3D.values():\n            self.points3D.append(point.xyz)\n            self.points3D_color.append(point.color)\n\n        self.points3D = torch.tensor(\n            np.array(self.points3D), dtype=torch.float32\n        )\n        self.points3D_color = torch.tensor(\n            np.array(self.points3D_color), dtype=torch.float32\n        )\n        self.points3D_color = self.points3D_color / 255.0\n"
  },
  {
    "path": "external/CMakeLists.txt",
    "content": "if(PIP_GLFW)\n  set(USE_PIP_GLFW\n    True\n    PARENT_SCOPE)\n  set(GLFW_LIBRARY\n      \"\"\n      PARENT_SCOPE)\n  set(GLFW_INCLUDES\n      ${CMAKE_SOURCE_DIR}/external/submodules/glfw/include\n      PARENT_SCOPE)\nelse()\n  set(USE_PIP_GLFW\n    False\n    PARENT_SCOPE)\n  set(GLFW_BUILD_EXAMPLES\n      OFF\n      CACHE BOOL \"\" FORCE)\n  set(GLFW_BUILD_TESTS\n      OFF\n      CACHE BOOL \"\" FORCE)\n  set(GLFW_BUILD_DOCS\n      OFF\n      CACHE BOOL \"\" FORCE)\n  add_subdirectory(submodules/glfw)\n  set(GLFW_LIBRARY\n      glfw\n      PARENT_SCOPE)\n  set(GLFW_INCLUDES\n      \"\"\n      PARENT_SCOPE)\n  message(STATUS \"GLFW not found from pip, building from source\")\nendif()\n\nadd_library(gl3w STATIC gl3w/gl3w.c)\ntarget_include_directories(gl3w PUBLIC \"include\")\n\nadd_library(\n  imgui STATIC\n  submodules/imgui/imgui.cpp\n  submodules/imgui/imgui_draw.cpp\n  submodules/imgui/imgui_demo.cpp\n  submodules/imgui/imgui_widgets.cpp\n  submodules/imgui/imgui_tables.cpp\n  submodules/imgui/backends/imgui_impl_glfw.cpp\n  submodules/imgui/backends/imgui_impl_opengl3.cpp)\ntarget_include_directories(\n  imgui PUBLIC \"submodules/imgui\" \"submodules/glfw/include\"\n               \"submodules/mesa/include\")\n\nfind_package(TBB GLOBAL)\nif(NOT TBB_FOUND)\n    add_subdirectory(submodules/tbb)\nendif()\n\nset(RADFOAM_EXTERNAL_INCLUDES\n    \"${CMAKE_SOURCE_DIR}/external/include\"\n    \"${CMAKE_SOURCE_DIR}/external/submodules/imgui\"\n    \"${CMAKE_SOURCE_DIR}/external/submodules/imgui/backends\"\n    PARENT_SCOPE)\n"
  },
  {
    "path": "external/gl3w/gl3w.c",
    "content": "/*\n * This file was generated with gl3w_gen.py, part of gl3w\n * (hosted at https://github.com/skaslev/gl3w)\n *\n * This is free and unencumbered software released into the public domain.\n *\n * Anyone is free to copy, modify, publish, use, compile, sell, or\n * distribute this software, either in source code form or as a compiled\n * binary, for any purpose, commercial or non-commercial, and by any\n * means.\n *\n * In jurisdictions that recognize copyright laws, the author or authors\n * of this software dedicate any and all copyright interest in the\n * software to the public domain. We make this dedication for the benefit\n * of the public at large and to the detriment of our heirs and\n * successors. We intend this dedication to be an overt act of\n * relinquishment in perpetuity of all present and future rights to this\n * software under copyright law.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include <GL/gl3w.h>\n#include <stdlib.h>\n\n#define ARRAY_SIZE(x)  (sizeof(x) / sizeof((x)[0]))\n\n#if defined(_WIN32)\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN 1\n#endif\n#include <windows.h>\n\nstatic HMODULE libgl;\ntypedef PROC(__stdcall* GL3WglGetProcAddr)(LPCSTR);\nstatic GL3WglGetProcAddr wgl_get_proc_address;\n\nstatic int open_libgl(void)\n{\n\tlibgl = LoadLibraryA(\"opengl32.dll\");\n\tif (!libgl)\n\t\treturn GL3W_ERROR_LIBRARY_OPEN;\n\n\twgl_get_proc_address = (GL3WglGetProcAddr)GetProcAddress(libgl, \"wglGetProcAddress\");\n\treturn GL3W_OK;\n}\n\nstatic void close_libgl(void)\n{\n\tFreeLibrary(libgl);\n}\n\nstatic GL3WglProc get_proc(const char *proc)\n{\n\tGL3WglProc res;\n\n\tres = (GL3WglProc)wgl_get_proc_address(proc);\n\tif (!res)\n\t\tres = (GL3WglProc)GetProcAddress(libgl, proc);\n\treturn res;\n}\n#elif defined(__APPLE__)\n#include <dlfcn.h>\n\nstatic void *libgl;\n\nstatic int open_libgl(void)\n{\n\tlibgl = dlopen(\"/System/Library/Frameworks/OpenGL.framework/OpenGL\", RTLD_LAZY | RTLD_LOCAL);\n\tif (!libgl)\n\t\treturn GL3W_ERROR_LIBRARY_OPEN;\n\n\treturn GL3W_OK;\n}\n\nstatic void close_libgl(void)\n{\n\tdlclose(libgl);\n}\n\nstatic GL3WglProc get_proc(const char *proc)\n{\n\tGL3WglProc res;\n\n\t*(void **)(&res) = dlsym(libgl, proc);\n\treturn res;\n}\n#else\n#include <dlfcn.h>\n\nstatic void *libgl;  /* OpenGL library */\nstatic void *libglx;  /* GLX library */\nstatic void *libegl;  /* EGL library */\nstatic GL3WGetProcAddressProc gl_get_proc_address;\n\nstatic void close_libgl(void)\n{\n\tif (libgl) {\n\t\tdlclose(libgl);\n\t\tlibgl = NULL;\n\t}\n\tif (libegl) {\n\t\tdlclose(libegl);\n\t\tlibegl = NULL;\n\t}\n\tif (libglx) {\n\t\tdlclose(libglx);\n\t\tlibglx = NULL;\n\t}\n}\n\nstatic int is_library_loaded(const char *name, void **lib)\n{\n\t*lib = dlopen(name, RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);\n\treturn *lib != NULL;\n}\n\nstatic int open_libs(void)\n{\n\t/* On Linux we have two APIs to get process addresses: EGL and GLX.\n\t * EGL is supported under both X11 and Wayland, whereas GLX is X11-specific.\n\t * First check what's already loaded, the windowing library might have\n\t * already loaded either EGL or GLX and we want to use the same one.\n\t */\n\n\tif (is_library_loaded(\"libEGL.so.1\", &libegl) ||\n\t\t\tis_library_loaded(\"libGLX.so.0\", &libglx)) {\n\t\tlibgl = dlopen(\"libOpenGL.so.0\", RTLD_LAZY | RTLD_LOCAL);\n\t\tif (libgl)\n\t\t\treturn GL3W_OK;\n\t\telse\n\t\t\tclose_libgl();\n\t}\n\n\tif (is_library_loaded(\"libGL.so.1\", &libgl))\n\t\treturn GL3W_OK;\n\n\t/* Neither is already loaded, so we have to load one. Try EGL first\n\t * because it is supported under both X11 and Wayland.\n\t */\n\n\t/* Load OpenGL + EGL */\n\tlibgl = dlopen(\"libOpenGL.so.0\", RTLD_LAZY | RTLD_LOCAL);\n\tlibegl = dlopen(\"libEGL.so.1\", RTLD_LAZY | RTLD_LOCAL);\n\tif (libgl && libegl)\n\t\treturn GL3W_OK;\n\n\t/* Fall back to legacy libGL, which includes GLX */\n\tclose_libgl();\n\tlibgl = dlopen(\"libGL.so.1\", RTLD_LAZY | RTLD_LOCAL);\n\tif (libgl)\n\t\treturn GL3W_OK;\n\n\treturn GL3W_ERROR_LIBRARY_OPEN;\n}\n\nstatic int open_libgl(void)\n{\n\tint res = open_libs();\n\tif (res)\n\t\treturn res;\n\n\tif (libegl)\n\t\t*(void **)(&gl_get_proc_address) = dlsym(libegl, \"eglGetProcAddress\");\n\telse if (libglx)\n\t\t*(void **)(&gl_get_proc_address) = dlsym(libglx, \"glXGetProcAddressARB\");\n\telse\n\t\t*(void **)(&gl_get_proc_address) = dlsym(libgl, \"glXGetProcAddressARB\");\n\n\tif (!gl_get_proc_address) {\n\t\tclose_libgl();\n\t\treturn GL3W_ERROR_LIBRARY_OPEN;\n\t}\n\n\treturn GL3W_OK;\n}\n\nstatic GL3WglProc get_proc(const char *proc)\n{\n\tGL3WglProc res = NULL;\n\n\t/* Before EGL version 1.5, eglGetProcAddress doesn't support querying core\n\t * functions and may return a dummy function if we try, so try to load the\n\t * function from the GL library directly first.\n\t */\n\tif (libegl)\n\t\t*(void **)(&res) = dlsym(libgl, proc);\n\n\tif (!res)\n\t\tres = gl_get_proc_address(proc);\n\n\tif (!libegl && !res)\n\t\t*(void **)(&res) = dlsym(libgl, proc);\n\n\treturn res;\n}\n#endif\n\nstatic struct {\n\tint major, minor;\n} version;\n\nstatic int parse_version(void)\n{\n\tif (!glGetIntegerv)\n\t\treturn GL3W_ERROR_INIT;\n\n\tglGetIntegerv(GL_MAJOR_VERSION, &version.major);\n\tglGetIntegerv(GL_MINOR_VERSION, &version.minor);\n\n\tif (version.major < 3)\n\t\treturn GL3W_ERROR_OPENGL_VERSION;\n\treturn GL3W_OK;\n}\n\nstatic void load_procs(GL3WGetProcAddressProc proc);\n\nint gl3wInit(void)\n{\n\tint res;\n\n\tres = open_libgl();\n\tif (res)\n\t\treturn res;\n\n\tatexit(close_libgl);\n\treturn gl3wInit2(get_proc);\n}\n\nint gl3wInit2(GL3WGetProcAddressProc proc)\n{\n\tload_procs(proc);\n\treturn parse_version();\n}\n\nint gl3wIsSupported(int major, int minor)\n{\n\tif (major < 3)\n\t\treturn 0;\n\tif (version.major == major)\n\t\treturn version.minor >= minor;\n\treturn version.major >= major;\n}\n\nGL3WglProc gl3wGetProcAddress(const char *proc)\n{\n\treturn get_proc(proc);\n}\n\nstatic const char *proc_names[] = {\n\t\"glActiveShaderProgram\",\n\t\"glActiveTexture\",\n\t\"glAttachShader\",\n\t\"glBeginConditionalRender\",\n\t\"glBeginQuery\",\n\t\"glBeginQueryIndexed\",\n\t\"glBeginTransformFeedback\",\n\t\"glBindAttribLocation\",\n\t\"glBindBuffer\",\n\t\"glBindBufferBase\",\n\t\"glBindBufferRange\",\n\t\"glBindBuffersBase\",\n\t\"glBindBuffersRange\",\n\t\"glBindFragDataLocation\",\n\t\"glBindFragDataLocationIndexed\",\n\t\"glBindFramebuffer\",\n\t\"glBindImageTexture\",\n\t\"glBindImageTextures\",\n\t\"glBindProgramPipeline\",\n\t\"glBindRenderbuffer\",\n\t\"glBindSampler\",\n\t\"glBindSamplers\",\n\t\"glBindTexture\",\n\t\"glBindTextureUnit\",\n\t\"glBindTextures\",\n\t\"glBindTransformFeedback\",\n\t\"glBindVertexArray\",\n\t\"glBindVertexBuffer\",\n\t\"glBindVertexBuffers\",\n\t\"glBlendColor\",\n\t\"glBlendEquation\",\n\t\"glBlendEquationSeparate\",\n\t\"glBlendEquationSeparatei\",\n\t\"glBlendEquationi\",\n\t\"glBlendFunc\",\n\t\"glBlendFuncSeparate\",\n\t\"glBlendFuncSeparatei\",\n\t\"glBlendFunci\",\n\t\"glBlitFramebuffer\",\n\t\"glBlitNamedFramebuffer\",\n\t\"glBufferData\",\n\t\"glBufferStorage\",\n\t\"glBufferSubData\",\n\t\"glCheckFramebufferStatus\",\n\t\"glCheckNamedFramebufferStatus\",\n\t\"glClampColor\",\n\t\"glClear\",\n\t\"glClearBufferData\",\n\t\"glClearBufferSubData\",\n\t\"glClearBufferfi\",\n\t\"glClearBufferfv\",\n\t\"glClearBufferiv\",\n\t\"glClearBufferuiv\",\n\t\"glClearColor\",\n\t\"glClearDepth\",\n\t\"glClearDepthf\",\n\t\"glClearNamedBufferData\",\n\t\"glClearNamedBufferSubData\",\n\t\"glClearNamedFramebufferfi\",\n\t\"glClearNamedFramebufferfv\",\n\t\"glClearNamedFramebufferiv\",\n\t\"glClearNamedFramebufferuiv\",\n\t\"glClearStencil\",\n\t\"glClearTexImage\",\n\t\"glClearTexSubImage\",\n\t\"glClientWaitSync\",\n\t\"glClipControl\",\n\t\"glColorMask\",\n\t\"glColorMaski\",\n\t\"glCompileShader\",\n\t\"glCompressedTexImage1D\",\n\t\"glCompressedTexImage2D\",\n\t\"glCompressedTexImage3D\",\n\t\"glCompressedTexSubImage1D\",\n\t\"glCompressedTexSubImage2D\",\n\t\"glCompressedTexSubImage3D\",\n\t\"glCompressedTextureSubImage1D\",\n\t\"glCompressedTextureSubImage2D\",\n\t\"glCompressedTextureSubImage3D\",\n\t\"glCopyBufferSubData\",\n\t\"glCopyImageSubData\",\n\t\"glCopyNamedBufferSubData\",\n\t\"glCopyTexImage1D\",\n\t\"glCopyTexImage2D\",\n\t\"glCopyTexSubImage1D\",\n\t\"glCopyTexSubImage2D\",\n\t\"glCopyTexSubImage3D\",\n\t\"glCopyTextureSubImage1D\",\n\t\"glCopyTextureSubImage2D\",\n\t\"glCopyTextureSubImage3D\",\n\t\"glCreateBuffers\",\n\t\"glCreateFramebuffers\",\n\t\"glCreateProgram\",\n\t\"glCreateProgramPipelines\",\n\t\"glCreateQueries\",\n\t\"glCreateRenderbuffers\",\n\t\"glCreateSamplers\",\n\t\"glCreateShader\",\n\t\"glCreateShaderProgramv\",\n\t\"glCreateTextures\",\n\t\"glCreateTransformFeedbacks\",\n\t\"glCreateVertexArrays\",\n\t\"glCullFace\",\n\t\"glDebugMessageCallback\",\n\t\"glDebugMessageControl\",\n\t\"glDebugMessageInsert\",\n\t\"glDeleteBuffers\",\n\t\"glDeleteFramebuffers\",\n\t\"glDeleteProgram\",\n\t\"glDeleteProgramPipelines\",\n\t\"glDeleteQueries\",\n\t\"glDeleteRenderbuffers\",\n\t\"glDeleteSamplers\",\n\t\"glDeleteShader\",\n\t\"glDeleteSync\",\n\t\"glDeleteTextures\",\n\t\"glDeleteTransformFeedbacks\",\n\t\"glDeleteVertexArrays\",\n\t\"glDepthFunc\",\n\t\"glDepthMask\",\n\t\"glDepthRange\",\n\t\"glDepthRangeArrayv\",\n\t\"glDepthRangeIndexed\",\n\t\"glDepthRangef\",\n\t\"glDetachShader\",\n\t\"glDisable\",\n\t\"glDisableVertexArrayAttrib\",\n\t\"glDisableVertexAttribArray\",\n\t\"glDisablei\",\n\t\"glDispatchCompute\",\n\t\"glDispatchComputeIndirect\",\n\t\"glDrawArrays\",\n\t\"glDrawArraysIndirect\",\n\t\"glDrawArraysInstanced\",\n\t\"glDrawArraysInstancedBaseInstance\",\n\t\"glDrawBuffer\",\n\t\"glDrawBuffers\",\n\t\"glDrawElements\",\n\t\"glDrawElementsBaseVertex\",\n\t\"glDrawElementsIndirect\",\n\t\"glDrawElementsInstanced\",\n\t\"glDrawElementsInstancedBaseInstance\",\n\t\"glDrawElementsInstancedBaseVertex\",\n\t\"glDrawElementsInstancedBaseVertexBaseInstance\",\n\t\"glDrawRangeElements\",\n\t\"glDrawRangeElementsBaseVertex\",\n\t\"glDrawTransformFeedback\",\n\t\"glDrawTransformFeedbackInstanced\",\n\t\"glDrawTransformFeedbackStream\",\n\t\"glDrawTransformFeedbackStreamInstanced\",\n\t\"glEnable\",\n\t\"glEnableVertexArrayAttrib\",\n\t\"glEnableVertexAttribArray\",\n\t\"glEnablei\",\n\t\"glEndConditionalRender\",\n\t\"glEndQuery\",\n\t\"glEndQueryIndexed\",\n\t\"glEndTransformFeedback\",\n\t\"glFenceSync\",\n\t\"glFinish\",\n\t\"glFlush\",\n\t\"glFlushMappedBufferRange\",\n\t\"glFlushMappedNamedBufferRange\",\n\t\"glFramebufferParameteri\",\n\t\"glFramebufferParameteriMESA\",\n\t\"glFramebufferRenderbuffer\",\n\t\"glFramebufferTexture\",\n\t\"glFramebufferTexture1D\",\n\t\"glFramebufferTexture2D\",\n\t\"glFramebufferTexture3D\",\n\t\"glFramebufferTextureLayer\",\n\t\"glFrontFace\",\n\t\"glGenBuffers\",\n\t\"glGenFramebuffers\",\n\t\"glGenProgramPipelines\",\n\t\"glGenQueries\",\n\t\"glGenRenderbuffers\",\n\t\"glGenSamplers\",\n\t\"glGenTextures\",\n\t\"glGenTransformFeedbacks\",\n\t\"glGenVertexArrays\",\n\t\"glGenerateMipmap\",\n\t\"glGenerateTextureMipmap\",\n\t\"glGetActiveAtomicCounterBufferiv\",\n\t\"glGetActiveAttrib\",\n\t\"glGetActiveSubroutineName\",\n\t\"glGetActiveSubroutineUniformName\",\n\t\"glGetActiveSubroutineUniformiv\",\n\t\"glGetActiveUniform\",\n\t\"glGetActiveUniformBlockName\",\n\t\"glGetActiveUniformBlockiv\",\n\t\"glGetActiveUniformName\",\n\t\"glGetActiveUniformsiv\",\n\t\"glGetAttachedShaders\",\n\t\"glGetAttribLocation\",\n\t\"glGetBooleani_v\",\n\t\"glGetBooleanv\",\n\t\"glGetBufferParameteri64v\",\n\t\"glGetBufferParameteriv\",\n\t\"glGetBufferPointerv\",\n\t\"glGetBufferSubData\",\n\t\"glGetCompressedTexImage\",\n\t\"glGetCompressedTextureImage\",\n\t\"glGetCompressedTextureSubImage\",\n\t\"glGetDebugMessageLog\",\n\t\"glGetDoublei_v\",\n\t\"glGetDoublev\",\n\t\"glGetError\",\n\t\"glGetFloati_v\",\n\t\"glGetFloatv\",\n\t\"glGetFragDataIndex\",\n\t\"glGetFragDataLocation\",\n\t\"glGetFramebufferAttachmentParameteriv\",\n\t\"glGetFramebufferParameteriv\",\n\t\"glGetFramebufferParameterivMESA\",\n\t\"glGetGraphicsResetStatus\",\n\t\"glGetInteger64i_v\",\n\t\"glGetInteger64v\",\n\t\"glGetIntegeri_v\",\n\t\"glGetIntegerv\",\n\t\"glGetInternalformati64v\",\n\t\"glGetInternalformativ\",\n\t\"glGetMultisamplefv\",\n\t\"glGetNamedBufferParameteri64v\",\n\t\"glGetNamedBufferParameteriv\",\n\t\"glGetNamedBufferPointerv\",\n\t\"glGetNamedBufferSubData\",\n\t\"glGetNamedFramebufferAttachmentParameteriv\",\n\t\"glGetNamedFramebufferParameteriv\",\n\t\"glGetNamedRenderbufferParameteriv\",\n\t\"glGetObjectLabel\",\n\t\"glGetObjectPtrLabel\",\n\t\"glGetPointerv\",\n\t\"glGetProgramBinary\",\n\t\"glGetProgramInfoLog\",\n\t\"glGetProgramInterfaceiv\",\n\t\"glGetProgramPipelineInfoLog\",\n\t\"glGetProgramPipelineiv\",\n\t\"glGetProgramResourceIndex\",\n\t\"glGetProgramResourceLocation\",\n\t\"glGetProgramResourceLocationIndex\",\n\t\"glGetProgramResourceName\",\n\t\"glGetProgramResourceiv\",\n\t\"glGetProgramStageiv\",\n\t\"glGetProgramiv\",\n\t\"glGetQueryBufferObjecti64v\",\n\t\"glGetQueryBufferObjectiv\",\n\t\"glGetQueryBufferObjectui64v\",\n\t\"glGetQueryBufferObjectuiv\",\n\t\"glGetQueryIndexediv\",\n\t\"glGetQueryObjecti64v\",\n\t\"glGetQueryObjectiv\",\n\t\"glGetQueryObjectui64v\",\n\t\"glGetQueryObjectuiv\",\n\t\"glGetQueryiv\",\n\t\"glGetRenderbufferParameteriv\",\n\t\"glGetSamplerParameterIiv\",\n\t\"glGetSamplerParameterIuiv\",\n\t\"glGetSamplerParameterfv\",\n\t\"glGetSamplerParameteriv\",\n\t\"glGetShaderInfoLog\",\n\t\"glGetShaderPrecisionFormat\",\n\t\"glGetShaderSource\",\n\t\"glGetShaderiv\",\n\t\"glGetString\",\n\t\"glGetStringi\",\n\t\"glGetSubroutineIndex\",\n\t\"glGetSubroutineUniformLocation\",\n\t\"glGetSynciv\",\n\t\"glGetTexImage\",\n\t\"glGetTexLevelParameterfv\",\n\t\"glGetTexLevelParameteriv\",\n\t\"glGetTexParameterIiv\",\n\t\"glGetTexParameterIuiv\",\n\t\"glGetTexParameterfv\",\n\t\"glGetTexParameteriv\",\n\t\"glGetTextureImage\",\n\t\"glGetTextureLevelParameterfv\",\n\t\"glGetTextureLevelParameteriv\",\n\t\"glGetTextureParameterIiv\",\n\t\"glGetTextureParameterIuiv\",\n\t\"glGetTextureParameterfv\",\n\t\"glGetTextureParameteriv\",\n\t\"glGetTextureSubImage\",\n\t\"glGetTransformFeedbackVarying\",\n\t\"glGetTransformFeedbacki64_v\",\n\t\"glGetTransformFeedbacki_v\",\n\t\"glGetTransformFeedbackiv\",\n\t\"glGetUniformBlockIndex\",\n\t\"glGetUniformIndices\",\n\t\"glGetUniformLocation\",\n\t\"glGetUniformSubroutineuiv\",\n\t\"glGetUniformdv\",\n\t\"glGetUniformfv\",\n\t\"glGetUniformiv\",\n\t\"glGetUniformuiv\",\n\t\"glGetVertexArrayIndexed64iv\",\n\t\"glGetVertexArrayIndexediv\",\n\t\"glGetVertexArrayiv\",\n\t\"glGetVertexAttribIiv\",\n\t\"glGetVertexAttribIuiv\",\n\t\"glGetVertexAttribLdv\",\n\t\"glGetVertexAttribPointerv\",\n\t\"glGetVertexAttribdv\",\n\t\"glGetVertexAttribfv\",\n\t\"glGetVertexAttribiv\",\n\t\"glGetnCompressedTexImage\",\n\t\"glGetnTexImage\",\n\t\"glGetnUniformdv\",\n\t\"glGetnUniformfv\",\n\t\"glGetnUniformiv\",\n\t\"glGetnUniformuiv\",\n\t\"glHint\",\n\t\"glInvalidateBufferData\",\n\t\"glInvalidateBufferSubData\",\n\t\"glInvalidateFramebuffer\",\n\t\"glInvalidateNamedFramebufferData\",\n\t\"glInvalidateNamedFramebufferSubData\",\n\t\"glInvalidateSubFramebuffer\",\n\t\"glInvalidateTexImage\",\n\t\"glInvalidateTexSubImage\",\n\t\"glIsBuffer\",\n\t\"glIsEnabled\",\n\t\"glIsEnabledi\",\n\t\"glIsFramebuffer\",\n\t\"glIsProgram\",\n\t\"glIsProgramPipeline\",\n\t\"glIsQuery\",\n\t\"glIsRenderbuffer\",\n\t\"glIsSampler\",\n\t\"glIsShader\",\n\t\"glIsSync\",\n\t\"glIsTexture\",\n\t\"glIsTransformFeedback\",\n\t\"glIsVertexArray\",\n\t\"glLineWidth\",\n\t\"glLinkProgram\",\n\t\"glLogicOp\",\n\t\"glMapBuffer\",\n\t\"glMapBufferRange\",\n\t\"glMapNamedBuffer\",\n\t\"glMapNamedBufferRange\",\n\t\"glMemoryBarrier\",\n\t\"glMemoryBarrierByRegion\",\n\t\"glMinSampleShading\",\n\t\"glMultiDrawArrays\",\n\t\"glMultiDrawArraysIndirect\",\n\t\"glMultiDrawArraysIndirectCount\",\n\t\"glMultiDrawElements\",\n\t\"glMultiDrawElementsBaseVertex\",\n\t\"glMultiDrawElementsIndirect\",\n\t\"glMultiDrawElementsIndirectCount\",\n\t\"glNamedBufferData\",\n\t\"glNamedBufferStorage\",\n\t\"glNamedBufferSubData\",\n\t\"glNamedFramebufferDrawBuffer\",\n\t\"glNamedFramebufferDrawBuffers\",\n\t\"glNamedFramebufferParameteri\",\n\t\"glNamedFramebufferReadBuffer\",\n\t\"glNamedFramebufferRenderbuffer\",\n\t\"glNamedFramebufferTexture\",\n\t\"glNamedFramebufferTextureLayer\",\n\t\"glNamedRenderbufferStorage\",\n\t\"glNamedRenderbufferStorageMultisample\",\n\t\"glObjectLabel\",\n\t\"glObjectPtrLabel\",\n\t\"glPatchParameterfv\",\n\t\"glPatchParameteri\",\n\t\"glPauseTransformFeedback\",\n\t\"glPixelStoref\",\n\t\"glPixelStorei\",\n\t\"glPointParameterf\",\n\t\"glPointParameterfv\",\n\t\"glPointParameteri\",\n\t\"glPointParameteriv\",\n\t\"glPointSize\",\n\t\"glPolygonMode\",\n\t\"glPolygonOffset\",\n\t\"glPolygonOffsetClamp\",\n\t\"glPopDebugGroup\",\n\t\"glPrimitiveRestartIndex\",\n\t\"glProgramBinary\",\n\t\"glProgramParameteri\",\n\t\"glProgramUniform1d\",\n\t\"glProgramUniform1dv\",\n\t\"glProgramUniform1f\",\n\t\"glProgramUniform1fv\",\n\t\"glProgramUniform1i\",\n\t\"glProgramUniform1iv\",\n\t\"glProgramUniform1ui\",\n\t\"glProgramUniform1uiv\",\n\t\"glProgramUniform2d\",\n\t\"glProgramUniform2dv\",\n\t\"glProgramUniform2f\",\n\t\"glProgramUniform2fv\",\n\t\"glProgramUniform2i\",\n\t\"glProgramUniform2iv\",\n\t\"glProgramUniform2ui\",\n\t\"glProgramUniform2uiv\",\n\t\"glProgramUniform3d\",\n\t\"glProgramUniform3dv\",\n\t\"glProgramUniform3f\",\n\t\"glProgramUniform3fv\",\n\t\"glProgramUniform3i\",\n\t\"glProgramUniform3iv\",\n\t\"glProgramUniform3ui\",\n\t\"glProgramUniform3uiv\",\n\t\"glProgramUniform4d\",\n\t\"glProgramUniform4dv\",\n\t\"glProgramUniform4f\",\n\t\"glProgramUniform4fv\",\n\t\"glProgramUniform4i\",\n\t\"glProgramUniform4iv\",\n\t\"glProgramUniform4ui\",\n\t\"glProgramUniform4uiv\",\n\t\"glProgramUniformMatrix2dv\",\n\t\"glProgramUniformMatrix2fv\",\n\t\"glProgramUniformMatrix2x3dv\",\n\t\"glProgramUniformMatrix2x3fv\",\n\t\"glProgramUniformMatrix2x4dv\",\n\t\"glProgramUniformMatrix2x4fv\",\n\t\"glProgramUniformMatrix3dv\",\n\t\"glProgramUniformMatrix3fv\",\n\t\"glProgramUniformMatrix3x2dv\",\n\t\"glProgramUniformMatrix3x2fv\",\n\t\"glProgramUniformMatrix3x4dv\",\n\t\"glProgramUniformMatrix3x4fv\",\n\t\"glProgramUniformMatrix4dv\",\n\t\"glProgramUniformMatrix4fv\",\n\t\"glProgramUniformMatrix4x2dv\",\n\t\"glProgramUniformMatrix4x2fv\",\n\t\"glProgramUniformMatrix4x3dv\",\n\t\"glProgramUniformMatrix4x3fv\",\n\t\"glProvokingVertex\",\n\t\"glPushDebugGroup\",\n\t\"glQueryCounter\",\n\t\"glReadBuffer\",\n\t\"glReadPixels\",\n\t\"glReadnPixels\",\n\t\"glReleaseShaderCompiler\",\n\t\"glRenderbufferStorage\",\n\t\"glRenderbufferStorageMultisample\",\n\t\"glResumeTransformFeedback\",\n\t\"glSampleCoverage\",\n\t\"glSampleMaski\",\n\t\"glSamplerParameterIiv\",\n\t\"glSamplerParameterIuiv\",\n\t\"glSamplerParameterf\",\n\t\"glSamplerParameterfv\",\n\t\"glSamplerParameteri\",\n\t\"glSamplerParameteriv\",\n\t\"glScissor\",\n\t\"glScissorArrayv\",\n\t\"glScissorIndexed\",\n\t\"glScissorIndexedv\",\n\t\"glShaderBinary\",\n\t\"glShaderSource\",\n\t\"glShaderStorageBlockBinding\",\n\t\"glSpecializeShader\",\n\t\"glStencilFunc\",\n\t\"glStencilFuncSeparate\",\n\t\"glStencilMask\",\n\t\"glStencilMaskSeparate\",\n\t\"glStencilOp\",\n\t\"glStencilOpSeparate\",\n\t\"glTexBuffer\",\n\t\"glTexBufferRange\",\n\t\"glTexImage1D\",\n\t\"glTexImage2D\",\n\t\"glTexImage2DMultisample\",\n\t\"glTexImage3D\",\n\t\"glTexImage3DMultisample\",\n\t\"glTexParameterIiv\",\n\t\"glTexParameterIuiv\",\n\t\"glTexParameterf\",\n\t\"glTexParameterfv\",\n\t\"glTexParameteri\",\n\t\"glTexParameteriv\",\n\t\"glTexStorage1D\",\n\t\"glTexStorage2D\",\n\t\"glTexStorage2DMultisample\",\n\t\"glTexStorage3D\",\n\t\"glTexStorage3DMultisample\",\n\t\"glTexSubImage1D\",\n\t\"glTexSubImage2D\",\n\t\"glTexSubImage3D\",\n\t\"glTextureBarrier\",\n\t\"glTextureBuffer\",\n\t\"glTextureBufferRange\",\n\t\"glTextureParameterIiv\",\n\t\"glTextureParameterIuiv\",\n\t\"glTextureParameterf\",\n\t\"glTextureParameterfv\",\n\t\"glTextureParameteri\",\n\t\"glTextureParameteriv\",\n\t\"glTextureStorage1D\",\n\t\"glTextureStorage2D\",\n\t\"glTextureStorage2DMultisample\",\n\t\"glTextureStorage3D\",\n\t\"glTextureStorage3DMultisample\",\n\t\"glTextureSubImage1D\",\n\t\"glTextureSubImage2D\",\n\t\"glTextureSubImage3D\",\n\t\"glTextureView\",\n\t\"glTransformFeedbackBufferBase\",\n\t\"glTransformFeedbackBufferRange\",\n\t\"glTransformFeedbackVaryings\",\n\t\"glUniform1d\",\n\t\"glUniform1dv\",\n\t\"glUniform1f\",\n\t\"glUniform1fv\",\n\t\"glUniform1i\",\n\t\"glUniform1iv\",\n\t\"glUniform1ui\",\n\t\"glUniform1uiv\",\n\t\"glUniform2d\",\n\t\"glUniform2dv\",\n\t\"glUniform2f\",\n\t\"glUniform2fv\",\n\t\"glUniform2i\",\n\t\"glUniform2iv\",\n\t\"glUniform2ui\",\n\t\"glUniform2uiv\",\n\t\"glUniform3d\",\n\t\"glUniform3dv\",\n\t\"glUniform3f\",\n\t\"glUniform3fv\",\n\t\"glUniform3i\",\n\t\"glUniform3iv\",\n\t\"glUniform3ui\",\n\t\"glUniform3uiv\",\n\t\"glUniform4d\",\n\t\"glUniform4dv\",\n\t\"glUniform4f\",\n\t\"glUniform4fv\",\n\t\"glUniform4i\",\n\t\"glUniform4iv\",\n\t\"glUniform4ui\",\n\t\"glUniform4uiv\",\n\t\"glUniformBlockBinding\",\n\t\"glUniformMatrix2dv\",\n\t\"glUniformMatrix2fv\",\n\t\"glUniformMatrix2x3dv\",\n\t\"glUniformMatrix2x3fv\",\n\t\"glUniformMatrix2x4dv\",\n\t\"glUniformMatrix2x4fv\",\n\t\"glUniformMatrix3dv\",\n\t\"glUniformMatrix3fv\",\n\t\"glUniformMatrix3x2dv\",\n\t\"glUniformMatrix3x2fv\",\n\t\"glUniformMatrix3x4dv\",\n\t\"glUniformMatrix3x4fv\",\n\t\"glUniformMatrix4dv\",\n\t\"glUniformMatrix4fv\",\n\t\"glUniformMatrix4x2dv\",\n\t\"glUniformMatrix4x2fv\",\n\t\"glUniformMatrix4x3dv\",\n\t\"glUniformMatrix4x3fv\",\n\t\"glUniformSubroutinesuiv\",\n\t\"glUnmapBuffer\",\n\t\"glUnmapNamedBuffer\",\n\t\"glUseProgram\",\n\t\"glUseProgramStages\",\n\t\"glValidateProgram\",\n\t\"glValidateProgramPipeline\",\n\t\"glVertexArrayAttribBinding\",\n\t\"glVertexArrayAttribFormat\",\n\t\"glVertexArrayAttribIFormat\",\n\t\"glVertexArrayAttribLFormat\",\n\t\"glVertexArrayBindingDivisor\",\n\t\"glVertexArrayElementBuffer\",\n\t\"glVertexArrayVertexBuffer\",\n\t\"glVertexArrayVertexBuffers\",\n\t\"glVertexAttrib1d\",\n\t\"glVertexAttrib1dv\",\n\t\"glVertexAttrib1f\",\n\t\"glVertexAttrib1fv\",\n\t\"glVertexAttrib1s\",\n\t\"glVertexAttrib1sv\",\n\t\"glVertexAttrib2d\",\n\t\"glVertexAttrib2dv\",\n\t\"glVertexAttrib2f\",\n\t\"glVertexAttrib2fv\",\n\t\"glVertexAttrib2s\",\n\t\"glVertexAttrib2sv\",\n\t\"glVertexAttrib3d\",\n\t\"glVertexAttrib3dv\",\n\t\"glVertexAttrib3f\",\n\t\"glVertexAttrib3fv\",\n\t\"glVertexAttrib3s\",\n\t\"glVertexAttrib3sv\",\n\t\"glVertexAttrib4Nbv\",\n\t\"glVertexAttrib4Niv\",\n\t\"glVertexAttrib4Nsv\",\n\t\"glVertexAttrib4Nub\",\n\t\"glVertexAttrib4Nubv\",\n\t\"glVertexAttrib4Nuiv\",\n\t\"glVertexAttrib4Nusv\",\n\t\"glVertexAttrib4bv\",\n\t\"glVertexAttrib4d\",\n\t\"glVertexAttrib4dv\",\n\t\"glVertexAttrib4f\",\n\t\"glVertexAttrib4fv\",\n\t\"glVertexAttrib4iv\",\n\t\"glVertexAttrib4s\",\n\t\"glVertexAttrib4sv\",\n\t\"glVertexAttrib4ubv\",\n\t\"glVertexAttrib4uiv\",\n\t\"glVertexAttrib4usv\",\n\t\"glVertexAttribBinding\",\n\t\"glVertexAttribDivisor\",\n\t\"glVertexAttribFormat\",\n\t\"glVertexAttribI1i\",\n\t\"glVertexAttribI1iv\",\n\t\"glVertexAttribI1ui\",\n\t\"glVertexAttribI1uiv\",\n\t\"glVertexAttribI2i\",\n\t\"glVertexAttribI2iv\",\n\t\"glVertexAttribI2ui\",\n\t\"glVertexAttribI2uiv\",\n\t\"glVertexAttribI3i\",\n\t\"glVertexAttribI3iv\",\n\t\"glVertexAttribI3ui\",\n\t\"glVertexAttribI3uiv\",\n\t\"glVertexAttribI4bv\",\n\t\"glVertexAttribI4i\",\n\t\"glVertexAttribI4iv\",\n\t\"glVertexAttribI4sv\",\n\t\"glVertexAttribI4ubv\",\n\t\"glVertexAttribI4ui\",\n\t\"glVertexAttribI4uiv\",\n\t\"glVertexAttribI4usv\",\n\t\"glVertexAttribIFormat\",\n\t\"glVertexAttribIPointer\",\n\t\"glVertexAttribL1d\",\n\t\"glVertexAttribL1dv\",\n\t\"glVertexAttribL2d\",\n\t\"glVertexAttribL2dv\",\n\t\"glVertexAttribL3d\",\n\t\"glVertexAttribL3dv\",\n\t\"glVertexAttribL4d\",\n\t\"glVertexAttribL4dv\",\n\t\"glVertexAttribLFormat\",\n\t\"glVertexAttribLPointer\",\n\t\"glVertexAttribP1ui\",\n\t\"glVertexAttribP1uiv\",\n\t\"glVertexAttribP2ui\",\n\t\"glVertexAttribP2uiv\",\n\t\"glVertexAttribP3ui\",\n\t\"glVertexAttribP3uiv\",\n\t\"glVertexAttribP4ui\",\n\t\"glVertexAttribP4uiv\",\n\t\"glVertexAttribPointer\",\n\t\"glVertexBindingDivisor\",\n\t\"glViewport\",\n\t\"glViewportArrayv\",\n\t\"glViewportIndexedf\",\n\t\"glViewportIndexedfv\",\n\t\"glWaitSync\",\n};\n\nGL3W_API union GL3WProcs gl3wProcs;\n\nstatic void load_procs(GL3WGetProcAddressProc proc)\n{\n\tsize_t i;\n\n\tfor (i = 0; i < ARRAY_SIZE(proc_names); i++)\n\t\tgl3wProcs.ptr[i] = proc(proc_names[i]);\n}\n"
  },
  {
    "path": "external/include/GL/gl3w.h",
    "content": "/*\n * This file was generated with gl3w_gen.py, part of gl3w\n * (hosted at https://github.com/skaslev/gl3w)\n *\n * This is free and unencumbered software released into the public domain.\n *\n * Anyone is free to copy, modify, publish, use, compile, sell, or\n * distribute this software, either in source code form or as a compiled\n * binary, for any purpose, commercial or non-commercial, and by any\n * means.\n *\n * In jurisdictions that recognize copyright laws, the author or authors\n * of this software dedicate any and all copyright interest in the\n * software to the public domain. We make this dedication for the benefit\n * of the public at large and to the detriment of our heirs and\n * successors. We intend this dedication to be an overt act of\n * relinquishment in perpetuity of all present and future rights to this\n * software under copyright law.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef __gl3w_h_\n#define __gl3w_h_\n\n#include <GL/glcorearb.h>\n\n#ifndef GL3W_API\n#define GL3W_API\n#endif\n\n#ifndef __gl_h_\n#define __gl_h_\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define GL3W_OK 0\n#define GL3W_ERROR_INIT -1\n#define GL3W_ERROR_LIBRARY_OPEN -2\n#define GL3W_ERROR_OPENGL_VERSION -3\n\ntypedef void (*GL3WglProc)(void);\ntypedef GL3WglProc (*GL3WGetProcAddressProc)(const char *proc);\n\n/* gl3w api */\nGL3W_API int gl3wInit(void);\nGL3W_API int gl3wInit2(GL3WGetProcAddressProc proc);\nGL3W_API int gl3wIsSupported(int major, int minor);\nGL3W_API GL3WglProc gl3wGetProcAddress(const char *proc);\n\n/* gl3w internal state */\nunion GL3WProcs {\n\tGL3WglProc ptr[659];\n\tstruct {\n\t\tPFNGLACTIVESHADERPROGRAMPROC                            ActiveShaderProgram;\n\t\tPFNGLACTIVETEXTUREPROC                                  ActiveTexture;\n\t\tPFNGLATTACHSHADERPROC                                   AttachShader;\n\t\tPFNGLBEGINCONDITIONALRENDERPROC                         BeginConditionalRender;\n\t\tPFNGLBEGINQUERYPROC                                     BeginQuery;\n\t\tPFNGLBEGINQUERYINDEXEDPROC                              BeginQueryIndexed;\n\t\tPFNGLBEGINTRANSFORMFEEDBACKPROC                         BeginTransformFeedback;\n\t\tPFNGLBINDATTRIBLOCATIONPROC                             BindAttribLocation;\n\t\tPFNGLBINDBUFFERPROC                                     BindBuffer;\n\t\tPFNGLBINDBUFFERBASEPROC                                 BindBufferBase;\n\t\tPFNGLBINDBUFFERRANGEPROC                                BindBufferRange;\n\t\tPFNGLBINDBUFFERSBASEPROC                                BindBuffersBase;\n\t\tPFNGLBINDBUFFERSRANGEPROC                               BindBuffersRange;\n\t\tPFNGLBINDFRAGDATALOCATIONPROC                           BindFragDataLocation;\n\t\tPFNGLBINDFRAGDATALOCATIONINDEXEDPROC                    BindFragDataLocationIndexed;\n\t\tPFNGLBINDFRAMEBUFFERPROC                                BindFramebuffer;\n\t\tPFNGLBINDIMAGETEXTUREPROC                               BindImageTexture;\n\t\tPFNGLBINDIMAGETEXTURESPROC                              BindImageTextures;\n\t\tPFNGLBINDPROGRAMPIPELINEPROC                            BindProgramPipeline;\n\t\tPFNGLBINDRENDERBUFFERPROC                               BindRenderbuffer;\n\t\tPFNGLBINDSAMPLERPROC                                    BindSampler;\n\t\tPFNGLBINDSAMPLERSPROC                                   BindSamplers;\n\t\tPFNGLBINDTEXTUREPROC                                    BindTexture;\n\t\tPFNGLBINDTEXTUREUNITPROC                                BindTextureUnit;\n\t\tPFNGLBINDTEXTURESPROC                                   BindTextures;\n\t\tPFNGLBINDTRANSFORMFEEDBACKPROC                          BindTransformFeedback;\n\t\tPFNGLBINDVERTEXARRAYPROC                                BindVertexArray;\n\t\tPFNGLBINDVERTEXBUFFERPROC                               BindVertexBuffer;\n\t\tPFNGLBINDVERTEXBUFFERSPROC                              BindVertexBuffers;\n\t\tPFNGLBLENDCOLORPROC                                     BlendColor;\n\t\tPFNGLBLENDEQUATIONPROC                                  BlendEquation;\n\t\tPFNGLBLENDEQUATIONSEPARATEPROC                          BlendEquationSeparate;\n\t\tPFNGLBLENDEQUATIONSEPARATEIPROC                         BlendEquationSeparatei;\n\t\tPFNGLBLENDEQUATIONIPROC                                 BlendEquationi;\n\t\tPFNGLBLENDFUNCPROC                                      BlendFunc;\n\t\tPFNGLBLENDFUNCSEPARATEPROC                              BlendFuncSeparate;\n\t\tPFNGLBLENDFUNCSEPARATEIPROC                             BlendFuncSeparatei;\n\t\tPFNGLBLENDFUNCIPROC                                     BlendFunci;\n\t\tPFNGLBLITFRAMEBUFFERPROC                                BlitFramebuffer;\n\t\tPFNGLBLITNAMEDFRAMEBUFFERPROC                           BlitNamedFramebuffer;\n\t\tPFNGLBUFFERDATAPROC                                     BufferData;\n\t\tPFNGLBUFFERSTORAGEPROC                                  BufferStorage;\n\t\tPFNGLBUFFERSUBDATAPROC                                  BufferSubData;\n\t\tPFNGLCHECKFRAMEBUFFERSTATUSPROC                         CheckFramebufferStatus;\n\t\tPFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC                    CheckNamedFramebufferStatus;\n\t\tPFNGLCLAMPCOLORPROC                                     ClampColor;\n\t\tPFNGLCLEARPROC                                          Clear;\n\t\tPFNGLCLEARBUFFERDATAPROC                                ClearBufferData;\n\t\tPFNGLCLEARBUFFERSUBDATAPROC                             ClearBufferSubData;\n\t\tPFNGLCLEARBUFFERFIPROC                                  ClearBufferfi;\n\t\tPFNGLCLEARBUFFERFVPROC                                  ClearBufferfv;\n\t\tPFNGLCLEARBUFFERIVPROC                                  ClearBufferiv;\n\t\tPFNGLCLEARBUFFERUIVPROC                                 ClearBufferuiv;\n\t\tPFNGLCLEARCOLORPROC                                     ClearColor;\n\t\tPFNGLCLEARDEPTHPROC                                     ClearDepth;\n\t\tPFNGLCLEARDEPTHFPROC                                    ClearDepthf;\n\t\tPFNGLCLEARNAMEDBUFFERDATAPROC                           ClearNamedBufferData;\n\t\tPFNGLCLEARNAMEDBUFFERSUBDATAPROC                        ClearNamedBufferSubData;\n\t\tPFNGLCLEARNAMEDFRAMEBUFFERFIPROC                        ClearNamedFramebufferfi;\n\t\tPFNGLCLEARNAMEDFRAMEBUFFERFVPROC                        ClearNamedFramebufferfv;\n\t\tPFNGLCLEARNAMEDFRAMEBUFFERIVPROC                        ClearNamedFramebufferiv;\n\t\tPFNGLCLEARNAMEDFRAMEBUFFERUIVPROC                       ClearNamedFramebufferuiv;\n\t\tPFNGLCLEARSTENCILPROC                                   ClearStencil;\n\t\tPFNGLCLEARTEXIMAGEPROC                                  ClearTexImage;\n\t\tPFNGLCLEARTEXSUBIMAGEPROC                               ClearTexSubImage;\n\t\tPFNGLCLIENTWAITSYNCPROC                                 ClientWaitSync;\n\t\tPFNGLCLIPCONTROLPROC                                    ClipControl;\n\t\tPFNGLCOLORMASKPROC                                      ColorMask;\n\t\tPFNGLCOLORMASKIPROC                                     ColorMaski;\n\t\tPFNGLCOMPILESHADERPROC                                  CompileShader;\n\t\tPFNGLCOMPRESSEDTEXIMAGE1DPROC                           CompressedTexImage1D;\n\t\tPFNGLCOMPRESSEDTEXIMAGE2DPROC                           CompressedTexImage2D;\n\t\tPFNGLCOMPRESSEDTEXIMAGE3DPROC                           CompressedTexImage3D;\n\t\tPFNGLCOMPRESSEDTEXSUBIMAGE1DPROC                        CompressedTexSubImage1D;\n\t\tPFNGLCOMPRESSEDTEXSUBIMAGE2DPROC                        CompressedTexSubImage2D;\n\t\tPFNGLCOMPRESSEDTEXSUBIMAGE3DPROC                        CompressedTexSubImage3D;\n\t\tPFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC                    CompressedTextureSubImage1D;\n\t\tPFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC                    CompressedTextureSubImage2D;\n\t\tPFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC                    CompressedTextureSubImage3D;\n\t\tPFNGLCOPYBUFFERSUBDATAPROC                              CopyBufferSubData;\n\t\tPFNGLCOPYIMAGESUBDATAPROC                               CopyImageSubData;\n\t\tPFNGLCOPYNAMEDBUFFERSUBDATAPROC                         CopyNamedBufferSubData;\n\t\tPFNGLCOPYTEXIMAGE1DPROC                                 CopyTexImage1D;\n\t\tPFNGLCOPYTEXIMAGE2DPROC                                 CopyTexImage2D;\n\t\tPFNGLCOPYTEXSUBIMAGE1DPROC                              CopyTexSubImage1D;\n\t\tPFNGLCOPYTEXSUBIMAGE2DPROC                              CopyTexSubImage2D;\n\t\tPFNGLCOPYTEXSUBIMAGE3DPROC                              CopyTexSubImage3D;\n\t\tPFNGLCOPYTEXTURESUBIMAGE1DPROC                          CopyTextureSubImage1D;\n\t\tPFNGLCOPYTEXTURESUBIMAGE2DPROC                          CopyTextureSubImage2D;\n\t\tPFNGLCOPYTEXTURESUBIMAGE3DPROC                          CopyTextureSubImage3D;\n\t\tPFNGLCREATEBUFFERSPROC                                  CreateBuffers;\n\t\tPFNGLCREATEFRAMEBUFFERSPROC                             CreateFramebuffers;\n\t\tPFNGLCREATEPROGRAMPROC                                  CreateProgram;\n\t\tPFNGLCREATEPROGRAMPIPELINESPROC                         CreateProgramPipelines;\n\t\tPFNGLCREATEQUERIESPROC                                  CreateQueries;\n\t\tPFNGLCREATERENDERBUFFERSPROC                            CreateRenderbuffers;\n\t\tPFNGLCREATESAMPLERSPROC                                 CreateSamplers;\n\t\tPFNGLCREATESHADERPROC                                   CreateShader;\n\t\tPFNGLCREATESHADERPROGRAMVPROC                           CreateShaderProgramv;\n\t\tPFNGLCREATETEXTURESPROC                                 CreateTextures;\n\t\tPFNGLCREATETRANSFORMFEEDBACKSPROC                       CreateTransformFeedbacks;\n\t\tPFNGLCREATEVERTEXARRAYSPROC                             CreateVertexArrays;\n\t\tPFNGLCULLFACEPROC                                       CullFace;\n\t\tPFNGLDEBUGMESSAGECALLBACKPROC                           DebugMessageCallback;\n\t\tPFNGLDEBUGMESSAGECONTROLPROC                            DebugMessageControl;\n\t\tPFNGLDEBUGMESSAGEINSERTPROC                             DebugMessageInsert;\n\t\tPFNGLDELETEBUFFERSPROC                                  DeleteBuffers;\n\t\tPFNGLDELETEFRAMEBUFFERSPROC                             DeleteFramebuffers;\n\t\tPFNGLDELETEPROGRAMPROC                                  DeleteProgram;\n\t\tPFNGLDELETEPROGRAMPIPELINESPROC                         DeleteProgramPipelines;\n\t\tPFNGLDELETEQUERIESPROC                                  DeleteQueries;\n\t\tPFNGLDELETERENDERBUFFERSPROC                            DeleteRenderbuffers;\n\t\tPFNGLDELETESAMPLERSPROC                                 DeleteSamplers;\n\t\tPFNGLDELETESHADERPROC                                   DeleteShader;\n\t\tPFNGLDELETESYNCPROC                                     DeleteSync;\n\t\tPFNGLDELETETEXTURESPROC                                 DeleteTextures;\n\t\tPFNGLDELETETRANSFORMFEEDBACKSPROC                       DeleteTransformFeedbacks;\n\t\tPFNGLDELETEVERTEXARRAYSPROC                             DeleteVertexArrays;\n\t\tPFNGLDEPTHFUNCPROC                                      DepthFunc;\n\t\tPFNGLDEPTHMASKPROC                                      DepthMask;\n\t\tPFNGLDEPTHRANGEPROC                                     DepthRange;\n\t\tPFNGLDEPTHRANGEARRAYVPROC                               DepthRangeArrayv;\n\t\tPFNGLDEPTHRANGEINDEXEDPROC                              DepthRangeIndexed;\n\t\tPFNGLDEPTHRANGEFPROC                                    DepthRangef;\n\t\tPFNGLDETACHSHADERPROC                                   DetachShader;\n\t\tPFNGLDISABLEPROC                                        Disable;\n\t\tPFNGLDISABLEVERTEXARRAYATTRIBPROC                       DisableVertexArrayAttrib;\n\t\tPFNGLDISABLEVERTEXATTRIBARRAYPROC                       DisableVertexAttribArray;\n\t\tPFNGLDISABLEIPROC                                       Disablei;\n\t\tPFNGLDISPATCHCOMPUTEPROC                                DispatchCompute;\n\t\tPFNGLDISPATCHCOMPUTEINDIRECTPROC                        DispatchComputeIndirect;\n\t\tPFNGLDRAWARRAYSPROC                                     DrawArrays;\n\t\tPFNGLDRAWARRAYSINDIRECTPROC                             DrawArraysIndirect;\n\t\tPFNGLDRAWARRAYSINSTANCEDPROC                            DrawArraysInstanced;\n\t\tPFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC                DrawArraysInstancedBaseInstance;\n\t\tPFNGLDRAWBUFFERPROC                                     DrawBuffer;\n\t\tPFNGLDRAWBUFFERSPROC                                    DrawBuffers;\n\t\tPFNGLDRAWELEMENTSPROC                                   DrawElements;\n\t\tPFNGLDRAWELEMENTSBASEVERTEXPROC                         DrawElementsBaseVertex;\n\t\tPFNGLDRAWELEMENTSINDIRECTPROC                           DrawElementsIndirect;\n\t\tPFNGLDRAWELEMENTSINSTANCEDPROC                          DrawElementsInstanced;\n\t\tPFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC              DrawElementsInstancedBaseInstance;\n\t\tPFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC                DrawElementsInstancedBaseVertex;\n\t\tPFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC    DrawElementsInstancedBaseVertexBaseInstance;\n\t\tPFNGLDRAWRANGEELEMENTSPROC                              DrawRangeElements;\n\t\tPFNGLDRAWRANGEELEMENTSBASEVERTEXPROC                    DrawRangeElementsBaseVertex;\n\t\tPFNGLDRAWTRANSFORMFEEDBACKPROC                          DrawTransformFeedback;\n\t\tPFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC                 DrawTransformFeedbackInstanced;\n\t\tPFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC                    DrawTransformFeedbackStream;\n\t\tPFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC           DrawTransformFeedbackStreamInstanced;\n\t\tPFNGLENABLEPROC                                         Enable;\n\t\tPFNGLENABLEVERTEXARRAYATTRIBPROC                        EnableVertexArrayAttrib;\n\t\tPFNGLENABLEVERTEXATTRIBARRAYPROC                        EnableVertexAttribArray;\n\t\tPFNGLENABLEIPROC                                        Enablei;\n\t\tPFNGLENDCONDITIONALRENDERPROC                           EndConditionalRender;\n\t\tPFNGLENDQUERYPROC                                       EndQuery;\n\t\tPFNGLENDQUERYINDEXEDPROC                                EndQueryIndexed;\n\t\tPFNGLENDTRANSFORMFEEDBACKPROC                           EndTransformFeedback;\n\t\tPFNGLFENCESYNCPROC                                      FenceSync;\n\t\tPFNGLFINISHPROC                                         Finish;\n\t\tPFNGLFLUSHPROC                                          Flush;\n\t\tPFNGLFLUSHMAPPEDBUFFERRANGEPROC                         FlushMappedBufferRange;\n\t\tPFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC                    FlushMappedNamedBufferRange;\n\t\tPFNGLFRAMEBUFFERPARAMETERIPROC                          FramebufferParameteri;\n\t\tPFNGLFRAMEBUFFERPARAMETERIMESAPROC                      FramebufferParameteriMESA;\n\t\tPFNGLFRAMEBUFFERRENDERBUFFERPROC                        FramebufferRenderbuffer;\n\t\tPFNGLFRAMEBUFFERTEXTUREPROC                             FramebufferTexture;\n\t\tPFNGLFRAMEBUFFERTEXTURE1DPROC                           FramebufferTexture1D;\n\t\tPFNGLFRAMEBUFFERTEXTURE2DPROC                           FramebufferTexture2D;\n\t\tPFNGLFRAMEBUFFERTEXTURE3DPROC                           FramebufferTexture3D;\n\t\tPFNGLFRAMEBUFFERTEXTURELAYERPROC                        FramebufferTextureLayer;\n\t\tPFNGLFRONTFACEPROC                                      FrontFace;\n\t\tPFNGLGENBUFFERSPROC                                     GenBuffers;\n\t\tPFNGLGENFRAMEBUFFERSPROC                                GenFramebuffers;\n\t\tPFNGLGENPROGRAMPIPELINESPROC                            GenProgramPipelines;\n\t\tPFNGLGENQUERIESPROC                                     GenQueries;\n\t\tPFNGLGENRENDERBUFFERSPROC                               GenRenderbuffers;\n\t\tPFNGLGENSAMPLERSPROC                                    GenSamplers;\n\t\tPFNGLGENTEXTURESPROC                                    GenTextures;\n\t\tPFNGLGENTRANSFORMFEEDBACKSPROC                          GenTransformFeedbacks;\n\t\tPFNGLGENVERTEXARRAYSPROC                                GenVertexArrays;\n\t\tPFNGLGENERATEMIPMAPPROC                                 GenerateMipmap;\n\t\tPFNGLGENERATETEXTUREMIPMAPPROC                          GenerateTextureMipmap;\n\t\tPFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC                 GetActiveAtomicCounterBufferiv;\n\t\tPFNGLGETACTIVEATTRIBPROC                                GetActiveAttrib;\n\t\tPFNGLGETACTIVESUBROUTINENAMEPROC                        GetActiveSubroutineName;\n\t\tPFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC                 GetActiveSubroutineUniformName;\n\t\tPFNGLGETACTIVESUBROUTINEUNIFORMIVPROC                   GetActiveSubroutineUniformiv;\n\t\tPFNGLGETACTIVEUNIFORMPROC                               GetActiveUniform;\n\t\tPFNGLGETACTIVEUNIFORMBLOCKNAMEPROC                      GetActiveUniformBlockName;\n\t\tPFNGLGETACTIVEUNIFORMBLOCKIVPROC                        GetActiveUniformBlockiv;\n\t\tPFNGLGETACTIVEUNIFORMNAMEPROC                           GetActiveUniformName;\n\t\tPFNGLGETACTIVEUNIFORMSIVPROC                            GetActiveUniformsiv;\n\t\tPFNGLGETATTACHEDSHADERSPROC                             GetAttachedShaders;\n\t\tPFNGLGETATTRIBLOCATIONPROC                              GetAttribLocation;\n\t\tPFNGLGETBOOLEANI_VPROC                                  GetBooleani_v;\n\t\tPFNGLGETBOOLEANVPROC                                    GetBooleanv;\n\t\tPFNGLGETBUFFERPARAMETERI64VPROC                         GetBufferParameteri64v;\n\t\tPFNGLGETBUFFERPARAMETERIVPROC                           GetBufferParameteriv;\n\t\tPFNGLGETBUFFERPOINTERVPROC                              GetBufferPointerv;\n\t\tPFNGLGETBUFFERSUBDATAPROC                               GetBufferSubData;\n\t\tPFNGLGETCOMPRESSEDTEXIMAGEPROC                          GetCompressedTexImage;\n\t\tPFNGLGETCOMPRESSEDTEXTUREIMAGEPROC                      GetCompressedTextureImage;\n\t\tPFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC                   GetCompressedTextureSubImage;\n\t\tPFNGLGETDEBUGMESSAGELOGPROC                             GetDebugMessageLog;\n\t\tPFNGLGETDOUBLEI_VPROC                                   GetDoublei_v;\n\t\tPFNGLGETDOUBLEVPROC                                     GetDoublev;\n\t\tPFNGLGETERRORPROC                                       GetError;\n\t\tPFNGLGETFLOATI_VPROC                                    GetFloati_v;\n\t\tPFNGLGETFLOATVPROC                                      GetFloatv;\n\t\tPFNGLGETFRAGDATAINDEXPROC                               GetFragDataIndex;\n\t\tPFNGLGETFRAGDATALOCATIONPROC                            GetFragDataLocation;\n\t\tPFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC            GetFramebufferAttachmentParameteriv;\n\t\tPFNGLGETFRAMEBUFFERPARAMETERIVPROC                      GetFramebufferParameteriv;\n\t\tPFNGLGETFRAMEBUFFERPARAMETERIVMESAPROC                  GetFramebufferParameterivMESA;\n\t\tPFNGLGETGRAPHICSRESETSTATUSPROC                         GetGraphicsResetStatus;\n\t\tPFNGLGETINTEGER64I_VPROC                                GetInteger64i_v;\n\t\tPFNGLGETINTEGER64VPROC                                  GetInteger64v;\n\t\tPFNGLGETINTEGERI_VPROC                                  GetIntegeri_v;\n\t\tPFNGLGETINTEGERVPROC                                    GetIntegerv;\n\t\tPFNGLGETINTERNALFORMATI64VPROC                          GetInternalformati64v;\n\t\tPFNGLGETINTERNALFORMATIVPROC                            GetInternalformativ;\n\t\tPFNGLGETMULTISAMPLEFVPROC                               GetMultisamplefv;\n\t\tPFNGLGETNAMEDBUFFERPARAMETERI64VPROC                    GetNamedBufferParameteri64v;\n\t\tPFNGLGETNAMEDBUFFERPARAMETERIVPROC                      GetNamedBufferParameteriv;\n\t\tPFNGLGETNAMEDBUFFERPOINTERVPROC                         GetNamedBufferPointerv;\n\t\tPFNGLGETNAMEDBUFFERSUBDATAPROC                          GetNamedBufferSubData;\n\t\tPFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC       GetNamedFramebufferAttachmentParameteriv;\n\t\tPFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC                 GetNamedFramebufferParameteriv;\n\t\tPFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC                GetNamedRenderbufferParameteriv;\n\t\tPFNGLGETOBJECTLABELPROC                                 GetObjectLabel;\n\t\tPFNGLGETOBJECTPTRLABELPROC                              GetObjectPtrLabel;\n\t\tPFNGLGETPOINTERVPROC                                    GetPointerv;\n\t\tPFNGLGETPROGRAMBINARYPROC                               GetProgramBinary;\n\t\tPFNGLGETPROGRAMINFOLOGPROC                              GetProgramInfoLog;\n\t\tPFNGLGETPROGRAMINTERFACEIVPROC                          GetProgramInterfaceiv;\n\t\tPFNGLGETPROGRAMPIPELINEINFOLOGPROC                      GetProgramPipelineInfoLog;\n\t\tPFNGLGETPROGRAMPIPELINEIVPROC                           GetProgramPipelineiv;\n\t\tPFNGLGETPROGRAMRESOURCEINDEXPROC                        GetProgramResourceIndex;\n\t\tPFNGLGETPROGRAMRESOURCELOCATIONPROC                     GetProgramResourceLocation;\n\t\tPFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC                GetProgramResourceLocationIndex;\n\t\tPFNGLGETPROGRAMRESOURCENAMEPROC                         GetProgramResourceName;\n\t\tPFNGLGETPROGRAMRESOURCEIVPROC                           GetProgramResourceiv;\n\t\tPFNGLGETPROGRAMSTAGEIVPROC                              GetProgramStageiv;\n\t\tPFNGLGETPROGRAMIVPROC                                   GetProgramiv;\n\t\tPFNGLGETQUERYBUFFEROBJECTI64VPROC                       GetQueryBufferObjecti64v;\n\t\tPFNGLGETQUERYBUFFEROBJECTIVPROC                         GetQueryBufferObjectiv;\n\t\tPFNGLGETQUERYBUFFEROBJECTUI64VPROC                      GetQueryBufferObjectui64v;\n\t\tPFNGLGETQUERYBUFFEROBJECTUIVPROC                        GetQueryBufferObjectuiv;\n\t\tPFNGLGETQUERYINDEXEDIVPROC                              GetQueryIndexediv;\n\t\tPFNGLGETQUERYOBJECTI64VPROC                             GetQueryObjecti64v;\n\t\tPFNGLGETQUERYOBJECTIVPROC                               GetQueryObjectiv;\n\t\tPFNGLGETQUERYOBJECTUI64VPROC                            GetQueryObjectui64v;\n\t\tPFNGLGETQUERYOBJECTUIVPROC                              GetQueryObjectuiv;\n\t\tPFNGLGETQUERYIVPROC                                     GetQueryiv;\n\t\tPFNGLGETRENDERBUFFERPARAMETERIVPROC                     GetRenderbufferParameteriv;\n\t\tPFNGLGETSAMPLERPARAMETERIIVPROC                         GetSamplerParameterIiv;\n\t\tPFNGLGETSAMPLERPARAMETERIUIVPROC                        GetSamplerParameterIuiv;\n\t\tPFNGLGETSAMPLERPARAMETERFVPROC                          GetSamplerParameterfv;\n\t\tPFNGLGETSAMPLERPARAMETERIVPROC                          GetSamplerParameteriv;\n\t\tPFNGLGETSHADERINFOLOGPROC                               GetShaderInfoLog;\n\t\tPFNGLGETSHADERPRECISIONFORMATPROC                       GetShaderPrecisionFormat;\n\t\tPFNGLGETSHADERSOURCEPROC                                GetShaderSource;\n\t\tPFNGLGETSHADERIVPROC                                    GetShaderiv;\n\t\tPFNGLGETSTRINGPROC                                      GetString;\n\t\tPFNGLGETSTRINGIPROC                                     GetStringi;\n\t\tPFNGLGETSUBROUTINEINDEXPROC                             GetSubroutineIndex;\n\t\tPFNGLGETSUBROUTINEUNIFORMLOCATIONPROC                   GetSubroutineUniformLocation;\n\t\tPFNGLGETSYNCIVPROC                                      GetSynciv;\n\t\tPFNGLGETTEXIMAGEPROC                                    GetTexImage;\n\t\tPFNGLGETTEXLEVELPARAMETERFVPROC                         GetTexLevelParameterfv;\n\t\tPFNGLGETTEXLEVELPARAMETERIVPROC                         GetTexLevelParameteriv;\n\t\tPFNGLGETTEXPARAMETERIIVPROC                             GetTexParameterIiv;\n\t\tPFNGLGETTEXPARAMETERIUIVPROC                            GetTexParameterIuiv;\n\t\tPFNGLGETTEXPARAMETERFVPROC                              GetTexParameterfv;\n\t\tPFNGLGETTEXPARAMETERIVPROC                              GetTexParameteriv;\n\t\tPFNGLGETTEXTUREIMAGEPROC                                GetTextureImage;\n\t\tPFNGLGETTEXTURELEVELPARAMETERFVPROC                     GetTextureLevelParameterfv;\n\t\tPFNGLGETTEXTURELEVELPARAMETERIVPROC                     GetTextureLevelParameteriv;\n\t\tPFNGLGETTEXTUREPARAMETERIIVPROC                         GetTextureParameterIiv;\n\t\tPFNGLGETTEXTUREPARAMETERIUIVPROC                        GetTextureParameterIuiv;\n\t\tPFNGLGETTEXTUREPARAMETERFVPROC                          GetTextureParameterfv;\n\t\tPFNGLGETTEXTUREPARAMETERIVPROC                          GetTextureParameteriv;\n\t\tPFNGLGETTEXTURESUBIMAGEPROC                             GetTextureSubImage;\n\t\tPFNGLGETTRANSFORMFEEDBACKVARYINGPROC                    GetTransformFeedbackVarying;\n\t\tPFNGLGETTRANSFORMFEEDBACKI64_VPROC                      GetTransformFeedbacki64_v;\n\t\tPFNGLGETTRANSFORMFEEDBACKI_VPROC                        GetTransformFeedbacki_v;\n\t\tPFNGLGETTRANSFORMFEEDBACKIVPROC                         GetTransformFeedbackiv;\n\t\tPFNGLGETUNIFORMBLOCKINDEXPROC                           GetUniformBlockIndex;\n\t\tPFNGLGETUNIFORMINDICESPROC                              GetUniformIndices;\n\t\tPFNGLGETUNIFORMLOCATIONPROC                             GetUniformLocation;\n\t\tPFNGLGETUNIFORMSUBROUTINEUIVPROC                        GetUniformSubroutineuiv;\n\t\tPFNGLGETUNIFORMDVPROC                                   GetUniformdv;\n\t\tPFNGLGETUNIFORMFVPROC                                   GetUniformfv;\n\t\tPFNGLGETUNIFORMIVPROC                                   GetUniformiv;\n\t\tPFNGLGETUNIFORMUIVPROC                                  GetUniformuiv;\n\t\tPFNGLGETVERTEXARRAYINDEXED64IVPROC                      GetVertexArrayIndexed64iv;\n\t\tPFNGLGETVERTEXARRAYINDEXEDIVPROC                        GetVertexArrayIndexediv;\n\t\tPFNGLGETVERTEXARRAYIVPROC                               GetVertexArrayiv;\n\t\tPFNGLGETVERTEXATTRIBIIVPROC                             GetVertexAttribIiv;\n\t\tPFNGLGETVERTEXATTRIBIUIVPROC                            GetVertexAttribIuiv;\n\t\tPFNGLGETVERTEXATTRIBLDVPROC                             GetVertexAttribLdv;\n\t\tPFNGLGETVERTEXATTRIBPOINTERVPROC                        GetVertexAttribPointerv;\n\t\tPFNGLGETVERTEXATTRIBDVPROC                              GetVertexAttribdv;\n\t\tPFNGLGETVERTEXATTRIBFVPROC                              GetVertexAttribfv;\n\t\tPFNGLGETVERTEXATTRIBIVPROC                              GetVertexAttribiv;\n\t\tPFNGLGETNCOMPRESSEDTEXIMAGEPROC                         GetnCompressedTexImage;\n\t\tPFNGLGETNTEXIMAGEPROC                                   GetnTexImage;\n\t\tPFNGLGETNUNIFORMDVPROC                                  GetnUniformdv;\n\t\tPFNGLGETNUNIFORMFVPROC                                  GetnUniformfv;\n\t\tPFNGLGETNUNIFORMIVPROC                                  GetnUniformiv;\n\t\tPFNGLGETNUNIFORMUIVPROC                                 GetnUniformuiv;\n\t\tPFNGLHINTPROC                                           Hint;\n\t\tPFNGLINVALIDATEBUFFERDATAPROC                           InvalidateBufferData;\n\t\tPFNGLINVALIDATEBUFFERSUBDATAPROC                        InvalidateBufferSubData;\n\t\tPFNGLINVALIDATEFRAMEBUFFERPROC                          InvalidateFramebuffer;\n\t\tPFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC                 InvalidateNamedFramebufferData;\n\t\tPFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC              InvalidateNamedFramebufferSubData;\n\t\tPFNGLINVALIDATESUBFRAMEBUFFERPROC                       InvalidateSubFramebuffer;\n\t\tPFNGLINVALIDATETEXIMAGEPROC                             InvalidateTexImage;\n\t\tPFNGLINVALIDATETEXSUBIMAGEPROC                          InvalidateTexSubImage;\n\t\tPFNGLISBUFFERPROC                                       IsBuffer;\n\t\tPFNGLISENABLEDPROC                                      IsEnabled;\n\t\tPFNGLISENABLEDIPROC                                     IsEnabledi;\n\t\tPFNGLISFRAMEBUFFERPROC                                  IsFramebuffer;\n\t\tPFNGLISPROGRAMPROC                                      IsProgram;\n\t\tPFNGLISPROGRAMPIPELINEPROC                              IsProgramPipeline;\n\t\tPFNGLISQUERYPROC                                        IsQuery;\n\t\tPFNGLISRENDERBUFFERPROC                                 IsRenderbuffer;\n\t\tPFNGLISSAMPLERPROC                                      IsSampler;\n\t\tPFNGLISSHADERPROC                                       IsShader;\n\t\tPFNGLISSYNCPROC                                         IsSync;\n\t\tPFNGLISTEXTUREPROC                                      IsTexture;\n\t\tPFNGLISTRANSFORMFEEDBACKPROC                            IsTransformFeedback;\n\t\tPFNGLISVERTEXARRAYPROC                                  IsVertexArray;\n\t\tPFNGLLINEWIDTHPROC                                      LineWidth;\n\t\tPFNGLLINKPROGRAMPROC                                    LinkProgram;\n\t\tPFNGLLOGICOPPROC                                        LogicOp;\n\t\tPFNGLMAPBUFFERPROC                                      MapBuffer;\n\t\tPFNGLMAPBUFFERRANGEPROC                                 MapBufferRange;\n\t\tPFNGLMAPNAMEDBUFFERPROC                                 MapNamedBuffer;\n\t\tPFNGLMAPNAMEDBUFFERRANGEPROC                            MapNamedBufferRange;\n\t\tPFNGLMEMORYBARRIERPROC                                  MemoryBarrier;\n\t\tPFNGLMEMORYBARRIERBYREGIONPROC                          MemoryBarrierByRegion;\n\t\tPFNGLMINSAMPLESHADINGPROC                               MinSampleShading;\n\t\tPFNGLMULTIDRAWARRAYSPROC                                MultiDrawArrays;\n\t\tPFNGLMULTIDRAWARRAYSINDIRECTPROC                        MultiDrawArraysIndirect;\n\t\tPFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC                   MultiDrawArraysIndirectCount;\n\t\tPFNGLMULTIDRAWELEMENTSPROC                              MultiDrawElements;\n\t\tPFNGLMULTIDRAWELEMENTSBASEVERTEXPROC                    MultiDrawElementsBaseVertex;\n\t\tPFNGLMULTIDRAWELEMENTSINDIRECTPROC                      MultiDrawElementsIndirect;\n\t\tPFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC                 MultiDrawElementsIndirectCount;\n\t\tPFNGLNAMEDBUFFERDATAPROC                                NamedBufferData;\n\t\tPFNGLNAMEDBUFFERSTORAGEPROC                             NamedBufferStorage;\n\t\tPFNGLNAMEDBUFFERSUBDATAPROC                             NamedBufferSubData;\n\t\tPFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC                     NamedFramebufferDrawBuffer;\n\t\tPFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC                    NamedFramebufferDrawBuffers;\n\t\tPFNGLNAMEDFRAMEBUFFERPARAMETERIPROC                     NamedFramebufferParameteri;\n\t\tPFNGLNAMEDFRAMEBUFFERREADBUFFERPROC                     NamedFramebufferReadBuffer;\n\t\tPFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC                   NamedFramebufferRenderbuffer;\n\t\tPFNGLNAMEDFRAMEBUFFERTEXTUREPROC                        NamedFramebufferTexture;\n\t\tPFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC                   NamedFramebufferTextureLayer;\n\t\tPFNGLNAMEDRENDERBUFFERSTORAGEPROC                       NamedRenderbufferStorage;\n\t\tPFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC            NamedRenderbufferStorageMultisample;\n\t\tPFNGLOBJECTLABELPROC                                    ObjectLabel;\n\t\tPFNGLOBJECTPTRLABELPROC                                 ObjectPtrLabel;\n\t\tPFNGLPATCHPARAMETERFVPROC                               PatchParameterfv;\n\t\tPFNGLPATCHPARAMETERIPROC                                PatchParameteri;\n\t\tPFNGLPAUSETRANSFORMFEEDBACKPROC                         PauseTransformFeedback;\n\t\tPFNGLPIXELSTOREFPROC                                    PixelStoref;\n\t\tPFNGLPIXELSTOREIPROC                                    PixelStorei;\n\t\tPFNGLPOINTPARAMETERFPROC                                PointParameterf;\n\t\tPFNGLPOINTPARAMETERFVPROC                               PointParameterfv;\n\t\tPFNGLPOINTPARAMETERIPROC                                PointParameteri;\n\t\tPFNGLPOINTPARAMETERIVPROC                               PointParameteriv;\n\t\tPFNGLPOINTSIZEPROC                                      PointSize;\n\t\tPFNGLPOLYGONMODEPROC                                    PolygonMode;\n\t\tPFNGLPOLYGONOFFSETPROC                                  PolygonOffset;\n\t\tPFNGLPOLYGONOFFSETCLAMPPROC                             PolygonOffsetClamp;\n\t\tPFNGLPOPDEBUGGROUPPROC                                  PopDebugGroup;\n\t\tPFNGLPRIMITIVERESTARTINDEXPROC                          PrimitiveRestartIndex;\n\t\tPFNGLPROGRAMBINARYPROC                                  ProgramBinary;\n\t\tPFNGLPROGRAMPARAMETERIPROC                              ProgramParameteri;\n\t\tPFNGLPROGRAMUNIFORM1DPROC                               ProgramUniform1d;\n\t\tPFNGLPROGRAMUNIFORM1DVPROC                              ProgramUniform1dv;\n\t\tPFNGLPROGRAMUNIFORM1FPROC                               ProgramUniform1f;\n\t\tPFNGLPROGRAMUNIFORM1FVPROC                              ProgramUniform1fv;\n\t\tPFNGLPROGRAMUNIFORM1IPROC                               ProgramUniform1i;\n\t\tPFNGLPROGRAMUNIFORM1IVPROC                              ProgramUniform1iv;\n\t\tPFNGLPROGRAMUNIFORM1UIPROC                              ProgramUniform1ui;\n\t\tPFNGLPROGRAMUNIFORM1UIVPROC                             ProgramUniform1uiv;\n\t\tPFNGLPROGRAMUNIFORM2DPROC                               ProgramUniform2d;\n\t\tPFNGLPROGRAMUNIFORM2DVPROC                              ProgramUniform2dv;\n\t\tPFNGLPROGRAMUNIFORM2FPROC                               ProgramUniform2f;\n\t\tPFNGLPROGRAMUNIFORM2FVPROC                              ProgramUniform2fv;\n\t\tPFNGLPROGRAMUNIFORM2IPROC                               ProgramUniform2i;\n\t\tPFNGLPROGRAMUNIFORM2IVPROC                              ProgramUniform2iv;\n\t\tPFNGLPROGRAMUNIFORM2UIPROC                              ProgramUniform2ui;\n\t\tPFNGLPROGRAMUNIFORM2UIVPROC                             ProgramUniform2uiv;\n\t\tPFNGLPROGRAMUNIFORM3DPROC                               ProgramUniform3d;\n\t\tPFNGLPROGRAMUNIFORM3DVPROC                              ProgramUniform3dv;\n\t\tPFNGLPROGRAMUNIFORM3FPROC                               ProgramUniform3f;\n\t\tPFNGLPROGRAMUNIFORM3FVPROC                              ProgramUniform3fv;\n\t\tPFNGLPROGRAMUNIFORM3IPROC                               ProgramUniform3i;\n\t\tPFNGLPROGRAMUNIFORM3IVPROC                              ProgramUniform3iv;\n\t\tPFNGLPROGRAMUNIFORM3UIPROC                              ProgramUniform3ui;\n\t\tPFNGLPROGRAMUNIFORM3UIVPROC                             ProgramUniform3uiv;\n\t\tPFNGLPROGRAMUNIFORM4DPROC                               ProgramUniform4d;\n\t\tPFNGLPROGRAMUNIFORM4DVPROC                              ProgramUniform4dv;\n\t\tPFNGLPROGRAMUNIFORM4FPROC                               ProgramUniform4f;\n\t\tPFNGLPROGRAMUNIFORM4FVPROC                              ProgramUniform4fv;\n\t\tPFNGLPROGRAMUNIFORM4IPROC                               ProgramUniform4i;\n\t\tPFNGLPROGRAMUNIFORM4IVPROC                              ProgramUniform4iv;\n\t\tPFNGLPROGRAMUNIFORM4UIPROC                              ProgramUniform4ui;\n\t\tPFNGLPROGRAMUNIFORM4UIVPROC                             ProgramUniform4uiv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX2DVPROC                        ProgramUniformMatrix2dv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX2FVPROC                        ProgramUniformMatrix2fv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX2X3DVPROC                      ProgramUniformMatrix2x3dv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX2X3FVPROC                      ProgramUniformMatrix2x3fv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX2X4DVPROC                      ProgramUniformMatrix2x4dv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX2X4FVPROC                      ProgramUniformMatrix2x4fv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX3DVPROC                        ProgramUniformMatrix3dv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX3FVPROC                        ProgramUniformMatrix3fv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX3X2DVPROC                      ProgramUniformMatrix3x2dv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX3X2FVPROC                      ProgramUniformMatrix3x2fv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX3X4DVPROC                      ProgramUniformMatrix3x4dv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX3X4FVPROC                      ProgramUniformMatrix3x4fv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX4DVPROC                        ProgramUniformMatrix4dv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX4FVPROC                        ProgramUniformMatrix4fv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX4X2DVPROC                      ProgramUniformMatrix4x2dv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX4X2FVPROC                      ProgramUniformMatrix4x2fv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX4X3DVPROC                      ProgramUniformMatrix4x3dv;\n\t\tPFNGLPROGRAMUNIFORMMATRIX4X3FVPROC                      ProgramUniformMatrix4x3fv;\n\t\tPFNGLPROVOKINGVERTEXPROC                                ProvokingVertex;\n\t\tPFNGLPUSHDEBUGGROUPPROC                                 PushDebugGroup;\n\t\tPFNGLQUERYCOUNTERPROC                                   QueryCounter;\n\t\tPFNGLREADBUFFERPROC                                     ReadBuffer;\n\t\tPFNGLREADPIXELSPROC                                     ReadPixels;\n\t\tPFNGLREADNPIXELSPROC                                    ReadnPixels;\n\t\tPFNGLRELEASESHADERCOMPILERPROC                          ReleaseShaderCompiler;\n\t\tPFNGLRENDERBUFFERSTORAGEPROC                            RenderbufferStorage;\n\t\tPFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC                 RenderbufferStorageMultisample;\n\t\tPFNGLRESUMETRANSFORMFEEDBACKPROC                        ResumeTransformFeedback;\n\t\tPFNGLSAMPLECOVERAGEPROC                                 SampleCoverage;\n\t\tPFNGLSAMPLEMASKIPROC                                    SampleMaski;\n\t\tPFNGLSAMPLERPARAMETERIIVPROC                            SamplerParameterIiv;\n\t\tPFNGLSAMPLERPARAMETERIUIVPROC                           SamplerParameterIuiv;\n\t\tPFNGLSAMPLERPARAMETERFPROC                              SamplerParameterf;\n\t\tPFNGLSAMPLERPARAMETERFVPROC                             SamplerParameterfv;\n\t\tPFNGLSAMPLERPARAMETERIPROC                              SamplerParameteri;\n\t\tPFNGLSAMPLERPARAMETERIVPROC                             SamplerParameteriv;\n\t\tPFNGLSCISSORPROC                                        Scissor;\n\t\tPFNGLSCISSORARRAYVPROC                                  ScissorArrayv;\n\t\tPFNGLSCISSORINDEXEDPROC                                 ScissorIndexed;\n\t\tPFNGLSCISSORINDEXEDVPROC                                ScissorIndexedv;\n\t\tPFNGLSHADERBINARYPROC                                   ShaderBinary;\n\t\tPFNGLSHADERSOURCEPROC                                   ShaderSource;\n\t\tPFNGLSHADERSTORAGEBLOCKBINDINGPROC                      ShaderStorageBlockBinding;\n\t\tPFNGLSPECIALIZESHADERPROC                               SpecializeShader;\n\t\tPFNGLSTENCILFUNCPROC                                    StencilFunc;\n\t\tPFNGLSTENCILFUNCSEPARATEPROC                            StencilFuncSeparate;\n\t\tPFNGLSTENCILMASKPROC                                    StencilMask;\n\t\tPFNGLSTENCILMASKSEPARATEPROC                            StencilMaskSeparate;\n\t\tPFNGLSTENCILOPPROC                                      StencilOp;\n\t\tPFNGLSTENCILOPSEPARATEPROC                              StencilOpSeparate;\n\t\tPFNGLTEXBUFFERPROC                                      TexBuffer;\n\t\tPFNGLTEXBUFFERRANGEPROC                                 TexBufferRange;\n\t\tPFNGLTEXIMAGE1DPROC                                     TexImage1D;\n\t\tPFNGLTEXIMAGE2DPROC                                     TexImage2D;\n\t\tPFNGLTEXIMAGE2DMULTISAMPLEPROC                          TexImage2DMultisample;\n\t\tPFNGLTEXIMAGE3DPROC                                     TexImage3D;\n\t\tPFNGLTEXIMAGE3DMULTISAMPLEPROC                          TexImage3DMultisample;\n\t\tPFNGLTEXPARAMETERIIVPROC                                TexParameterIiv;\n\t\tPFNGLTEXPARAMETERIUIVPROC                               TexParameterIuiv;\n\t\tPFNGLTEXPARAMETERFPROC                                  TexParameterf;\n\t\tPFNGLTEXPARAMETERFVPROC                                 TexParameterfv;\n\t\tPFNGLTEXPARAMETERIPROC                                  TexParameteri;\n\t\tPFNGLTEXPARAMETERIVPROC                                 TexParameteriv;\n\t\tPFNGLTEXSTORAGE1DPROC                                   TexStorage1D;\n\t\tPFNGLTEXSTORAGE2DPROC                                   TexStorage2D;\n\t\tPFNGLTEXSTORAGE2DMULTISAMPLEPROC                        TexStorage2DMultisample;\n\t\tPFNGLTEXSTORAGE3DPROC                                   TexStorage3D;\n\t\tPFNGLTEXSTORAGE3DMULTISAMPLEPROC                        TexStorage3DMultisample;\n\t\tPFNGLTEXSUBIMAGE1DPROC                                  TexSubImage1D;\n\t\tPFNGLTEXSUBIMAGE2DPROC                                  TexSubImage2D;\n\t\tPFNGLTEXSUBIMAGE3DPROC                                  TexSubImage3D;\n\t\tPFNGLTEXTUREBARRIERPROC                                 TextureBarrier;\n\t\tPFNGLTEXTUREBUFFERPROC                                  TextureBuffer;\n\t\tPFNGLTEXTUREBUFFERRANGEPROC                             TextureBufferRange;\n\t\tPFNGLTEXTUREPARAMETERIIVPROC                            TextureParameterIiv;\n\t\tPFNGLTEXTUREPARAMETERIUIVPROC                           TextureParameterIuiv;\n\t\tPFNGLTEXTUREPARAMETERFPROC                              TextureParameterf;\n\t\tPFNGLTEXTUREPARAMETERFVPROC                             TextureParameterfv;\n\t\tPFNGLTEXTUREPARAMETERIPROC                              TextureParameteri;\n\t\tPFNGLTEXTUREPARAMETERIVPROC                             TextureParameteriv;\n\t\tPFNGLTEXTURESTORAGE1DPROC                               TextureStorage1D;\n\t\tPFNGLTEXTURESTORAGE2DPROC                               TextureStorage2D;\n\t\tPFNGLTEXTURESTORAGE2DMULTISAMPLEPROC                    TextureStorage2DMultisample;\n\t\tPFNGLTEXTURESTORAGE3DPROC                               TextureStorage3D;\n\t\tPFNGLTEXTURESTORAGE3DMULTISAMPLEPROC                    TextureStorage3DMultisample;\n\t\tPFNGLTEXTURESUBIMAGE1DPROC                              TextureSubImage1D;\n\t\tPFNGLTEXTURESUBIMAGE2DPROC                              TextureSubImage2D;\n\t\tPFNGLTEXTURESUBIMAGE3DPROC                              TextureSubImage3D;\n\t\tPFNGLTEXTUREVIEWPROC                                    TextureView;\n\t\tPFNGLTRANSFORMFEEDBACKBUFFERBASEPROC                    TransformFeedbackBufferBase;\n\t\tPFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC                   TransformFeedbackBufferRange;\n\t\tPFNGLTRANSFORMFEEDBACKVARYINGSPROC                      TransformFeedbackVaryings;\n\t\tPFNGLUNIFORM1DPROC                                      Uniform1d;\n\t\tPFNGLUNIFORM1DVPROC                                     Uniform1dv;\n\t\tPFNGLUNIFORM1FPROC                                      Uniform1f;\n\t\tPFNGLUNIFORM1FVPROC                                     Uniform1fv;\n\t\tPFNGLUNIFORM1IPROC                                      Uniform1i;\n\t\tPFNGLUNIFORM1IVPROC                                     Uniform1iv;\n\t\tPFNGLUNIFORM1UIPROC                                     Uniform1ui;\n\t\tPFNGLUNIFORM1UIVPROC                                    Uniform1uiv;\n\t\tPFNGLUNIFORM2DPROC                                      Uniform2d;\n\t\tPFNGLUNIFORM2DVPROC                                     Uniform2dv;\n\t\tPFNGLUNIFORM2FPROC                                      Uniform2f;\n\t\tPFNGLUNIFORM2FVPROC                                     Uniform2fv;\n\t\tPFNGLUNIFORM2IPROC                                      Uniform2i;\n\t\tPFNGLUNIFORM2IVPROC                                     Uniform2iv;\n\t\tPFNGLUNIFORM2UIPROC                                     Uniform2ui;\n\t\tPFNGLUNIFORM2UIVPROC                                    Uniform2uiv;\n\t\tPFNGLUNIFORM3DPROC                                      Uniform3d;\n\t\tPFNGLUNIFORM3DVPROC                                     Uniform3dv;\n\t\tPFNGLUNIFORM3FPROC                                      Uniform3f;\n\t\tPFNGLUNIFORM3FVPROC                                     Uniform3fv;\n\t\tPFNGLUNIFORM3IPROC                                      Uniform3i;\n\t\tPFNGLUNIFORM3IVPROC                                     Uniform3iv;\n\t\tPFNGLUNIFORM3UIPROC                                     Uniform3ui;\n\t\tPFNGLUNIFORM3UIVPROC                                    Uniform3uiv;\n\t\tPFNGLUNIFORM4DPROC                                      Uniform4d;\n\t\tPFNGLUNIFORM4DVPROC                                     Uniform4dv;\n\t\tPFNGLUNIFORM4FPROC                                      Uniform4f;\n\t\tPFNGLUNIFORM4FVPROC                                     Uniform4fv;\n\t\tPFNGLUNIFORM4IPROC                                      Uniform4i;\n\t\tPFNGLUNIFORM4IVPROC                                     Uniform4iv;\n\t\tPFNGLUNIFORM4UIPROC                                     Uniform4ui;\n\t\tPFNGLUNIFORM4UIVPROC                                    Uniform4uiv;\n\t\tPFNGLUNIFORMBLOCKBINDINGPROC                            UniformBlockBinding;\n\t\tPFNGLUNIFORMMATRIX2DVPROC                               UniformMatrix2dv;\n\t\tPFNGLUNIFORMMATRIX2FVPROC                               UniformMatrix2fv;\n\t\tPFNGLUNIFORMMATRIX2X3DVPROC                             UniformMatrix2x3dv;\n\t\tPFNGLUNIFORMMATRIX2X3FVPROC                             UniformMatrix2x3fv;\n\t\tPFNGLUNIFORMMATRIX2X4DVPROC                             UniformMatrix2x4dv;\n\t\tPFNGLUNIFORMMATRIX2X4FVPROC                             UniformMatrix2x4fv;\n\t\tPFNGLUNIFORMMATRIX3DVPROC                               UniformMatrix3dv;\n\t\tPFNGLUNIFORMMATRIX3FVPROC                               UniformMatrix3fv;\n\t\tPFNGLUNIFORMMATRIX3X2DVPROC                             UniformMatrix3x2dv;\n\t\tPFNGLUNIFORMMATRIX3X2FVPROC                             UniformMatrix3x2fv;\n\t\tPFNGLUNIFORMMATRIX3X4DVPROC                             UniformMatrix3x4dv;\n\t\tPFNGLUNIFORMMATRIX3X4FVPROC                             UniformMatrix3x4fv;\n\t\tPFNGLUNIFORMMATRIX4DVPROC                               UniformMatrix4dv;\n\t\tPFNGLUNIFORMMATRIX4FVPROC                               UniformMatrix4fv;\n\t\tPFNGLUNIFORMMATRIX4X2DVPROC                             UniformMatrix4x2dv;\n\t\tPFNGLUNIFORMMATRIX4X2FVPROC                             UniformMatrix4x2fv;\n\t\tPFNGLUNIFORMMATRIX4X3DVPROC                             UniformMatrix4x3dv;\n\t\tPFNGLUNIFORMMATRIX4X3FVPROC                             UniformMatrix4x3fv;\n\t\tPFNGLUNIFORMSUBROUTINESUIVPROC                          UniformSubroutinesuiv;\n\t\tPFNGLUNMAPBUFFERPROC                                    UnmapBuffer;\n\t\tPFNGLUNMAPNAMEDBUFFERPROC                               UnmapNamedBuffer;\n\t\tPFNGLUSEPROGRAMPROC                                     UseProgram;\n\t\tPFNGLUSEPROGRAMSTAGESPROC                               UseProgramStages;\n\t\tPFNGLVALIDATEPROGRAMPROC                                ValidateProgram;\n\t\tPFNGLVALIDATEPROGRAMPIPELINEPROC                        ValidateProgramPipeline;\n\t\tPFNGLVERTEXARRAYATTRIBBINDINGPROC                       VertexArrayAttribBinding;\n\t\tPFNGLVERTEXARRAYATTRIBFORMATPROC                        VertexArrayAttribFormat;\n\t\tPFNGLVERTEXARRAYATTRIBIFORMATPROC                       VertexArrayAttribIFormat;\n\t\tPFNGLVERTEXARRAYATTRIBLFORMATPROC                       VertexArrayAttribLFormat;\n\t\tPFNGLVERTEXARRAYBINDINGDIVISORPROC                      VertexArrayBindingDivisor;\n\t\tPFNGLVERTEXARRAYELEMENTBUFFERPROC                       VertexArrayElementBuffer;\n\t\tPFNGLVERTEXARRAYVERTEXBUFFERPROC                        VertexArrayVertexBuffer;\n\t\tPFNGLVERTEXARRAYVERTEXBUFFERSPROC                       VertexArrayVertexBuffers;\n\t\tPFNGLVERTEXATTRIB1DPROC                                 VertexAttrib1d;\n\t\tPFNGLVERTEXATTRIB1DVPROC                                VertexAttrib1dv;\n\t\tPFNGLVERTEXATTRIB1FPROC                                 VertexAttrib1f;\n\t\tPFNGLVERTEXATTRIB1FVPROC                                VertexAttrib1fv;\n\t\tPFNGLVERTEXATTRIB1SPROC                                 VertexAttrib1s;\n\t\tPFNGLVERTEXATTRIB1SVPROC                                VertexAttrib1sv;\n\t\tPFNGLVERTEXATTRIB2DPROC                                 VertexAttrib2d;\n\t\tPFNGLVERTEXATTRIB2DVPROC                                VertexAttrib2dv;\n\t\tPFNGLVERTEXATTRIB2FPROC                                 VertexAttrib2f;\n\t\tPFNGLVERTEXATTRIB2FVPROC                                VertexAttrib2fv;\n\t\tPFNGLVERTEXATTRIB2SPROC                                 VertexAttrib2s;\n\t\tPFNGLVERTEXATTRIB2SVPROC                                VertexAttrib2sv;\n\t\tPFNGLVERTEXATTRIB3DPROC                                 VertexAttrib3d;\n\t\tPFNGLVERTEXATTRIB3DVPROC                                VertexAttrib3dv;\n\t\tPFNGLVERTEXATTRIB3FPROC                                 VertexAttrib3f;\n\t\tPFNGLVERTEXATTRIB3FVPROC                                VertexAttrib3fv;\n\t\tPFNGLVERTEXATTRIB3SPROC                                 VertexAttrib3s;\n\t\tPFNGLVERTEXATTRIB3SVPROC                                VertexAttrib3sv;\n\t\tPFNGLVERTEXATTRIB4NBVPROC                               VertexAttrib4Nbv;\n\t\tPFNGLVERTEXATTRIB4NIVPROC                               VertexAttrib4Niv;\n\t\tPFNGLVERTEXATTRIB4NSVPROC                               VertexAttrib4Nsv;\n\t\tPFNGLVERTEXATTRIB4NUBPROC                               VertexAttrib4Nub;\n\t\tPFNGLVERTEXATTRIB4NUBVPROC                              VertexAttrib4Nubv;\n\t\tPFNGLVERTEXATTRIB4NUIVPROC                              VertexAttrib4Nuiv;\n\t\tPFNGLVERTEXATTRIB4NUSVPROC                              VertexAttrib4Nusv;\n\t\tPFNGLVERTEXATTRIB4BVPROC                                VertexAttrib4bv;\n\t\tPFNGLVERTEXATTRIB4DPROC                                 VertexAttrib4d;\n\t\tPFNGLVERTEXATTRIB4DVPROC                                VertexAttrib4dv;\n\t\tPFNGLVERTEXATTRIB4FPROC                                 VertexAttrib4f;\n\t\tPFNGLVERTEXATTRIB4FVPROC                                VertexAttrib4fv;\n\t\tPFNGLVERTEXATTRIB4IVPROC                                VertexAttrib4iv;\n\t\tPFNGLVERTEXATTRIB4SPROC                                 VertexAttrib4s;\n\t\tPFNGLVERTEXATTRIB4SVPROC                                VertexAttrib4sv;\n\t\tPFNGLVERTEXATTRIB4UBVPROC                               VertexAttrib4ubv;\n\t\tPFNGLVERTEXATTRIB4UIVPROC                               VertexAttrib4uiv;\n\t\tPFNGLVERTEXATTRIB4USVPROC                               VertexAttrib4usv;\n\t\tPFNGLVERTEXATTRIBBINDINGPROC                            VertexAttribBinding;\n\t\tPFNGLVERTEXATTRIBDIVISORPROC                            VertexAttribDivisor;\n\t\tPFNGLVERTEXATTRIBFORMATPROC                             VertexAttribFormat;\n\t\tPFNGLVERTEXATTRIBI1IPROC                                VertexAttribI1i;\n\t\tPFNGLVERTEXATTRIBI1IVPROC                               VertexAttribI1iv;\n\t\tPFNGLVERTEXATTRIBI1UIPROC                               VertexAttribI1ui;\n\t\tPFNGLVERTEXATTRIBI1UIVPROC                              VertexAttribI1uiv;\n\t\tPFNGLVERTEXATTRIBI2IPROC                                VertexAttribI2i;\n\t\tPFNGLVERTEXATTRIBI2IVPROC                               VertexAttribI2iv;\n\t\tPFNGLVERTEXATTRIBI2UIPROC                               VertexAttribI2ui;\n\t\tPFNGLVERTEXATTRIBI2UIVPROC                              VertexAttribI2uiv;\n\t\tPFNGLVERTEXATTRIBI3IPROC                                VertexAttribI3i;\n\t\tPFNGLVERTEXATTRIBI3IVPROC                               VertexAttribI3iv;\n\t\tPFNGLVERTEXATTRIBI3UIPROC                               VertexAttribI3ui;\n\t\tPFNGLVERTEXATTRIBI3UIVPROC                              VertexAttribI3uiv;\n\t\tPFNGLVERTEXATTRIBI4BVPROC                               VertexAttribI4bv;\n\t\tPFNGLVERTEXATTRIBI4IPROC                                VertexAttribI4i;\n\t\tPFNGLVERTEXATTRIBI4IVPROC                               VertexAttribI4iv;\n\t\tPFNGLVERTEXATTRIBI4SVPROC                               VertexAttribI4sv;\n\t\tPFNGLVERTEXATTRIBI4UBVPROC                              VertexAttribI4ubv;\n\t\tPFNGLVERTEXATTRIBI4UIPROC                               VertexAttribI4ui;\n\t\tPFNGLVERTEXATTRIBI4UIVPROC                              VertexAttribI4uiv;\n\t\tPFNGLVERTEXATTRIBI4USVPROC                              VertexAttribI4usv;\n\t\tPFNGLVERTEXATTRIBIFORMATPROC                            VertexAttribIFormat;\n\t\tPFNGLVERTEXATTRIBIPOINTERPROC                           VertexAttribIPointer;\n\t\tPFNGLVERTEXATTRIBL1DPROC                                VertexAttribL1d;\n\t\tPFNGLVERTEXATTRIBL1DVPROC                               VertexAttribL1dv;\n\t\tPFNGLVERTEXATTRIBL2DPROC                                VertexAttribL2d;\n\t\tPFNGLVERTEXATTRIBL2DVPROC                               VertexAttribL2dv;\n\t\tPFNGLVERTEXATTRIBL3DPROC                                VertexAttribL3d;\n\t\tPFNGLVERTEXATTRIBL3DVPROC                               VertexAttribL3dv;\n\t\tPFNGLVERTEXATTRIBL4DPROC                                VertexAttribL4d;\n\t\tPFNGLVERTEXATTRIBL4DVPROC                               VertexAttribL4dv;\n\t\tPFNGLVERTEXATTRIBLFORMATPROC                            VertexAttribLFormat;\n\t\tPFNGLVERTEXATTRIBLPOINTERPROC                           VertexAttribLPointer;\n\t\tPFNGLVERTEXATTRIBP1UIPROC                               VertexAttribP1ui;\n\t\tPFNGLVERTEXATTRIBP1UIVPROC                              VertexAttribP1uiv;\n\t\tPFNGLVERTEXATTRIBP2UIPROC                               VertexAttribP2ui;\n\t\tPFNGLVERTEXATTRIBP2UIVPROC                              VertexAttribP2uiv;\n\t\tPFNGLVERTEXATTRIBP3UIPROC                               VertexAttribP3ui;\n\t\tPFNGLVERTEXATTRIBP3UIVPROC                              VertexAttribP3uiv;\n\t\tPFNGLVERTEXATTRIBP4UIPROC                               VertexAttribP4ui;\n\t\tPFNGLVERTEXATTRIBP4UIVPROC                              VertexAttribP4uiv;\n\t\tPFNGLVERTEXATTRIBPOINTERPROC                            VertexAttribPointer;\n\t\tPFNGLVERTEXBINDINGDIVISORPROC                           VertexBindingDivisor;\n\t\tPFNGLVIEWPORTPROC                                       Viewport;\n\t\tPFNGLVIEWPORTARRAYVPROC                                 ViewportArrayv;\n\t\tPFNGLVIEWPORTINDEXEDFPROC                               ViewportIndexedf;\n\t\tPFNGLVIEWPORTINDEXEDFVPROC                              ViewportIndexedfv;\n\t\tPFNGLWAITSYNCPROC                                       WaitSync;\n\t} gl;\n};\n\nGL3W_API extern union GL3WProcs gl3wProcs;\n\n/* OpenGL functions */\n#define glActiveShaderProgram                            gl3wProcs.gl.ActiveShaderProgram\n#define glActiveTexture                                  gl3wProcs.gl.ActiveTexture\n#define glAttachShader                                   gl3wProcs.gl.AttachShader\n#define glBeginConditionalRender                         gl3wProcs.gl.BeginConditionalRender\n#define glBeginQuery                                     gl3wProcs.gl.BeginQuery\n#define glBeginQueryIndexed                              gl3wProcs.gl.BeginQueryIndexed\n#define glBeginTransformFeedback                         gl3wProcs.gl.BeginTransformFeedback\n#define glBindAttribLocation                             gl3wProcs.gl.BindAttribLocation\n#define glBindBuffer                                     gl3wProcs.gl.BindBuffer\n#define glBindBufferBase                                 gl3wProcs.gl.BindBufferBase\n#define glBindBufferRange                                gl3wProcs.gl.BindBufferRange\n#define glBindBuffersBase                                gl3wProcs.gl.BindBuffersBase\n#define glBindBuffersRange                               gl3wProcs.gl.BindBuffersRange\n#define glBindFragDataLocation                           gl3wProcs.gl.BindFragDataLocation\n#define glBindFragDataLocationIndexed                    gl3wProcs.gl.BindFragDataLocationIndexed\n#define glBindFramebuffer                                gl3wProcs.gl.BindFramebuffer\n#define glBindImageTexture                               gl3wProcs.gl.BindImageTexture\n#define glBindImageTextures                              gl3wProcs.gl.BindImageTextures\n#define glBindProgramPipeline                            gl3wProcs.gl.BindProgramPipeline\n#define glBindRenderbuffer                               gl3wProcs.gl.BindRenderbuffer\n#define glBindSampler                                    gl3wProcs.gl.BindSampler\n#define glBindSamplers                                   gl3wProcs.gl.BindSamplers\n#define glBindTexture                                    gl3wProcs.gl.BindTexture\n#define glBindTextureUnit                                gl3wProcs.gl.BindTextureUnit\n#define glBindTextures                                   gl3wProcs.gl.BindTextures\n#define glBindTransformFeedback                          gl3wProcs.gl.BindTransformFeedback\n#define glBindVertexArray                                gl3wProcs.gl.BindVertexArray\n#define glBindVertexBuffer                               gl3wProcs.gl.BindVertexBuffer\n#define glBindVertexBuffers                              gl3wProcs.gl.BindVertexBuffers\n#define glBlendColor                                     gl3wProcs.gl.BlendColor\n#define glBlendEquation                                  gl3wProcs.gl.BlendEquation\n#define glBlendEquationSeparate                          gl3wProcs.gl.BlendEquationSeparate\n#define glBlendEquationSeparatei                         gl3wProcs.gl.BlendEquationSeparatei\n#define glBlendEquationi                                 gl3wProcs.gl.BlendEquationi\n#define glBlendFunc                                      gl3wProcs.gl.BlendFunc\n#define glBlendFuncSeparate                              gl3wProcs.gl.BlendFuncSeparate\n#define glBlendFuncSeparatei                             gl3wProcs.gl.BlendFuncSeparatei\n#define glBlendFunci                                     gl3wProcs.gl.BlendFunci\n#define glBlitFramebuffer                                gl3wProcs.gl.BlitFramebuffer\n#define glBlitNamedFramebuffer                           gl3wProcs.gl.BlitNamedFramebuffer\n#define glBufferData                                     gl3wProcs.gl.BufferData\n#define glBufferStorage                                  gl3wProcs.gl.BufferStorage\n#define glBufferSubData                                  gl3wProcs.gl.BufferSubData\n#define glCheckFramebufferStatus                         gl3wProcs.gl.CheckFramebufferStatus\n#define glCheckNamedFramebufferStatus                    gl3wProcs.gl.CheckNamedFramebufferStatus\n#define glClampColor                                     gl3wProcs.gl.ClampColor\n#define glClear                                          gl3wProcs.gl.Clear\n#define glClearBufferData                                gl3wProcs.gl.ClearBufferData\n#define glClearBufferSubData                             gl3wProcs.gl.ClearBufferSubData\n#define glClearBufferfi                                  gl3wProcs.gl.ClearBufferfi\n#define glClearBufferfv                                  gl3wProcs.gl.ClearBufferfv\n#define glClearBufferiv                                  gl3wProcs.gl.ClearBufferiv\n#define glClearBufferuiv                                 gl3wProcs.gl.ClearBufferuiv\n#define glClearColor                                     gl3wProcs.gl.ClearColor\n#define glClearDepth                                     gl3wProcs.gl.ClearDepth\n#define glClearDepthf                                    gl3wProcs.gl.ClearDepthf\n#define glClearNamedBufferData                           gl3wProcs.gl.ClearNamedBufferData\n#define glClearNamedBufferSubData                        gl3wProcs.gl.ClearNamedBufferSubData\n#define glClearNamedFramebufferfi                        gl3wProcs.gl.ClearNamedFramebufferfi\n#define glClearNamedFramebufferfv                        gl3wProcs.gl.ClearNamedFramebufferfv\n#define glClearNamedFramebufferiv                        gl3wProcs.gl.ClearNamedFramebufferiv\n#define glClearNamedFramebufferuiv                       gl3wProcs.gl.ClearNamedFramebufferuiv\n#define glClearStencil                                   gl3wProcs.gl.ClearStencil\n#define glClearTexImage                                  gl3wProcs.gl.ClearTexImage\n#define glClearTexSubImage                               gl3wProcs.gl.ClearTexSubImage\n#define glClientWaitSync                                 gl3wProcs.gl.ClientWaitSync\n#define glClipControl                                    gl3wProcs.gl.ClipControl\n#define glColorMask                                      gl3wProcs.gl.ColorMask\n#define glColorMaski                                     gl3wProcs.gl.ColorMaski\n#define glCompileShader                                  gl3wProcs.gl.CompileShader\n#define glCompressedTexImage1D                           gl3wProcs.gl.CompressedTexImage1D\n#define glCompressedTexImage2D                           gl3wProcs.gl.CompressedTexImage2D\n#define glCompressedTexImage3D                           gl3wProcs.gl.CompressedTexImage3D\n#define glCompressedTexSubImage1D                        gl3wProcs.gl.CompressedTexSubImage1D\n#define glCompressedTexSubImage2D                        gl3wProcs.gl.CompressedTexSubImage2D\n#define glCompressedTexSubImage3D                        gl3wProcs.gl.CompressedTexSubImage3D\n#define glCompressedTextureSubImage1D                    gl3wProcs.gl.CompressedTextureSubImage1D\n#define glCompressedTextureSubImage2D                    gl3wProcs.gl.CompressedTextureSubImage2D\n#define glCompressedTextureSubImage3D                    gl3wProcs.gl.CompressedTextureSubImage3D\n#define glCopyBufferSubData                              gl3wProcs.gl.CopyBufferSubData\n#define glCopyImageSubData                               gl3wProcs.gl.CopyImageSubData\n#define glCopyNamedBufferSubData                         gl3wProcs.gl.CopyNamedBufferSubData\n#define glCopyTexImage1D                                 gl3wProcs.gl.CopyTexImage1D\n#define glCopyTexImage2D                                 gl3wProcs.gl.CopyTexImage2D\n#define glCopyTexSubImage1D                              gl3wProcs.gl.CopyTexSubImage1D\n#define glCopyTexSubImage2D                              gl3wProcs.gl.CopyTexSubImage2D\n#define glCopyTexSubImage3D                              gl3wProcs.gl.CopyTexSubImage3D\n#define glCopyTextureSubImage1D                          gl3wProcs.gl.CopyTextureSubImage1D\n#define glCopyTextureSubImage2D                          gl3wProcs.gl.CopyTextureSubImage2D\n#define glCopyTextureSubImage3D                          gl3wProcs.gl.CopyTextureSubImage3D\n#define glCreateBuffers                                  gl3wProcs.gl.CreateBuffers\n#define glCreateFramebuffers                             gl3wProcs.gl.CreateFramebuffers\n#define glCreateProgram                                  gl3wProcs.gl.CreateProgram\n#define glCreateProgramPipelines                         gl3wProcs.gl.CreateProgramPipelines\n#define glCreateQueries                                  gl3wProcs.gl.CreateQueries\n#define glCreateRenderbuffers                            gl3wProcs.gl.CreateRenderbuffers\n#define glCreateSamplers                                 gl3wProcs.gl.CreateSamplers\n#define glCreateShader                                   gl3wProcs.gl.CreateShader\n#define glCreateShaderProgramv                           gl3wProcs.gl.CreateShaderProgramv\n#define glCreateTextures                                 gl3wProcs.gl.CreateTextures\n#define glCreateTransformFeedbacks                       gl3wProcs.gl.CreateTransformFeedbacks\n#define glCreateVertexArrays                             gl3wProcs.gl.CreateVertexArrays\n#define glCullFace                                       gl3wProcs.gl.CullFace\n#define glDebugMessageCallback                           gl3wProcs.gl.DebugMessageCallback\n#define glDebugMessageControl                            gl3wProcs.gl.DebugMessageControl\n#define glDebugMessageInsert                             gl3wProcs.gl.DebugMessageInsert\n#define glDeleteBuffers                                  gl3wProcs.gl.DeleteBuffers\n#define glDeleteFramebuffers                             gl3wProcs.gl.DeleteFramebuffers\n#define glDeleteProgram                                  gl3wProcs.gl.DeleteProgram\n#define glDeleteProgramPipelines                         gl3wProcs.gl.DeleteProgramPipelines\n#define glDeleteQueries                                  gl3wProcs.gl.DeleteQueries\n#define glDeleteRenderbuffers                            gl3wProcs.gl.DeleteRenderbuffers\n#define glDeleteSamplers                                 gl3wProcs.gl.DeleteSamplers\n#define glDeleteShader                                   gl3wProcs.gl.DeleteShader\n#define glDeleteSync                                     gl3wProcs.gl.DeleteSync\n#define glDeleteTextures                                 gl3wProcs.gl.DeleteTextures\n#define glDeleteTransformFeedbacks                       gl3wProcs.gl.DeleteTransformFeedbacks\n#define glDeleteVertexArrays                             gl3wProcs.gl.DeleteVertexArrays\n#define glDepthFunc                                      gl3wProcs.gl.DepthFunc\n#define glDepthMask                                      gl3wProcs.gl.DepthMask\n#define glDepthRange                                     gl3wProcs.gl.DepthRange\n#define glDepthRangeArrayv                               gl3wProcs.gl.DepthRangeArrayv\n#define glDepthRangeIndexed                              gl3wProcs.gl.DepthRangeIndexed\n#define glDepthRangef                                    gl3wProcs.gl.DepthRangef\n#define glDetachShader                                   gl3wProcs.gl.DetachShader\n#define glDisable                                        gl3wProcs.gl.Disable\n#define glDisableVertexArrayAttrib                       gl3wProcs.gl.DisableVertexArrayAttrib\n#define glDisableVertexAttribArray                       gl3wProcs.gl.DisableVertexAttribArray\n#define glDisablei                                       gl3wProcs.gl.Disablei\n#define glDispatchCompute                                gl3wProcs.gl.DispatchCompute\n#define glDispatchComputeIndirect                        gl3wProcs.gl.DispatchComputeIndirect\n#define glDrawArrays                                     gl3wProcs.gl.DrawArrays\n#define glDrawArraysIndirect                             gl3wProcs.gl.DrawArraysIndirect\n#define glDrawArraysInstanced                            gl3wProcs.gl.DrawArraysInstanced\n#define glDrawArraysInstancedBaseInstance                gl3wProcs.gl.DrawArraysInstancedBaseInstance\n#define glDrawBuffer                                     gl3wProcs.gl.DrawBuffer\n#define glDrawBuffers                                    gl3wProcs.gl.DrawBuffers\n#define glDrawElements                                   gl3wProcs.gl.DrawElements\n#define glDrawElementsBaseVertex                         gl3wProcs.gl.DrawElementsBaseVertex\n#define glDrawElementsIndirect                           gl3wProcs.gl.DrawElementsIndirect\n#define glDrawElementsInstanced                          gl3wProcs.gl.DrawElementsInstanced\n#define glDrawElementsInstancedBaseInstance              gl3wProcs.gl.DrawElementsInstancedBaseInstance\n#define glDrawElementsInstancedBaseVertex                gl3wProcs.gl.DrawElementsInstancedBaseVertex\n#define glDrawElementsInstancedBaseVertexBaseInstance    gl3wProcs.gl.DrawElementsInstancedBaseVertexBaseInstance\n#define glDrawRangeElements                              gl3wProcs.gl.DrawRangeElements\n#define glDrawRangeElementsBaseVertex                    gl3wProcs.gl.DrawRangeElementsBaseVertex\n#define glDrawTransformFeedback                          gl3wProcs.gl.DrawTransformFeedback\n#define glDrawTransformFeedbackInstanced                 gl3wProcs.gl.DrawTransformFeedbackInstanced\n#define glDrawTransformFeedbackStream                    gl3wProcs.gl.DrawTransformFeedbackStream\n#define glDrawTransformFeedbackStreamInstanced           gl3wProcs.gl.DrawTransformFeedbackStreamInstanced\n#define glEnable                                         gl3wProcs.gl.Enable\n#define glEnableVertexArrayAttrib                        gl3wProcs.gl.EnableVertexArrayAttrib\n#define glEnableVertexAttribArray                        gl3wProcs.gl.EnableVertexAttribArray\n#define glEnablei                                        gl3wProcs.gl.Enablei\n#define glEndConditionalRender                           gl3wProcs.gl.EndConditionalRender\n#define glEndQuery                                       gl3wProcs.gl.EndQuery\n#define glEndQueryIndexed                                gl3wProcs.gl.EndQueryIndexed\n#define glEndTransformFeedback                           gl3wProcs.gl.EndTransformFeedback\n#define glFenceSync                                      gl3wProcs.gl.FenceSync\n#define glFinish                                         gl3wProcs.gl.Finish\n#define glFlush                                          gl3wProcs.gl.Flush\n#define glFlushMappedBufferRange                         gl3wProcs.gl.FlushMappedBufferRange\n#define glFlushMappedNamedBufferRange                    gl3wProcs.gl.FlushMappedNamedBufferRange\n#define glFramebufferParameteri                          gl3wProcs.gl.FramebufferParameteri\n#define glFramebufferParameteriMESA                      gl3wProcs.gl.FramebufferParameteriMESA\n#define glFramebufferRenderbuffer                        gl3wProcs.gl.FramebufferRenderbuffer\n#define glFramebufferTexture                             gl3wProcs.gl.FramebufferTexture\n#define glFramebufferTexture1D                           gl3wProcs.gl.FramebufferTexture1D\n#define glFramebufferTexture2D                           gl3wProcs.gl.FramebufferTexture2D\n#define glFramebufferTexture3D                           gl3wProcs.gl.FramebufferTexture3D\n#define glFramebufferTextureLayer                        gl3wProcs.gl.FramebufferTextureLayer\n#define glFrontFace                                      gl3wProcs.gl.FrontFace\n#define glGenBuffers                                     gl3wProcs.gl.GenBuffers\n#define glGenFramebuffers                                gl3wProcs.gl.GenFramebuffers\n#define glGenProgramPipelines                            gl3wProcs.gl.GenProgramPipelines\n#define glGenQueries                                     gl3wProcs.gl.GenQueries\n#define glGenRenderbuffers                               gl3wProcs.gl.GenRenderbuffers\n#define glGenSamplers                                    gl3wProcs.gl.GenSamplers\n#define glGenTextures                                    gl3wProcs.gl.GenTextures\n#define glGenTransformFeedbacks                          gl3wProcs.gl.GenTransformFeedbacks\n#define glGenVertexArrays                                gl3wProcs.gl.GenVertexArrays\n#define glGenerateMipmap                                 gl3wProcs.gl.GenerateMipmap\n#define glGenerateTextureMipmap                          gl3wProcs.gl.GenerateTextureMipmap\n#define glGetActiveAtomicCounterBufferiv                 gl3wProcs.gl.GetActiveAtomicCounterBufferiv\n#define glGetActiveAttrib                                gl3wProcs.gl.GetActiveAttrib\n#define glGetActiveSubroutineName                        gl3wProcs.gl.GetActiveSubroutineName\n#define glGetActiveSubroutineUniformName                 gl3wProcs.gl.GetActiveSubroutineUniformName\n#define glGetActiveSubroutineUniformiv                   gl3wProcs.gl.GetActiveSubroutineUniformiv\n#define glGetActiveUniform                               gl3wProcs.gl.GetActiveUniform\n#define glGetActiveUniformBlockName                      gl3wProcs.gl.GetActiveUniformBlockName\n#define glGetActiveUniformBlockiv                        gl3wProcs.gl.GetActiveUniformBlockiv\n#define glGetActiveUniformName                           gl3wProcs.gl.GetActiveUniformName\n#define glGetActiveUniformsiv                            gl3wProcs.gl.GetActiveUniformsiv\n#define glGetAttachedShaders                             gl3wProcs.gl.GetAttachedShaders\n#define glGetAttribLocation                              gl3wProcs.gl.GetAttribLocation\n#define glGetBooleani_v                                  gl3wProcs.gl.GetBooleani_v\n#define glGetBooleanv                                    gl3wProcs.gl.GetBooleanv\n#define glGetBufferParameteri64v                         gl3wProcs.gl.GetBufferParameteri64v\n#define glGetBufferParameteriv                           gl3wProcs.gl.GetBufferParameteriv\n#define glGetBufferPointerv                              gl3wProcs.gl.GetBufferPointerv\n#define glGetBufferSubData                               gl3wProcs.gl.GetBufferSubData\n#define glGetCompressedTexImage                          gl3wProcs.gl.GetCompressedTexImage\n#define glGetCompressedTextureImage                      gl3wProcs.gl.GetCompressedTextureImage\n#define glGetCompressedTextureSubImage                   gl3wProcs.gl.GetCompressedTextureSubImage\n#define glGetDebugMessageLog                             gl3wProcs.gl.GetDebugMessageLog\n#define glGetDoublei_v                                   gl3wProcs.gl.GetDoublei_v\n#define glGetDoublev                                     gl3wProcs.gl.GetDoublev\n#define glGetError                                       gl3wProcs.gl.GetError\n#define glGetFloati_v                                    gl3wProcs.gl.GetFloati_v\n#define glGetFloatv                                      gl3wProcs.gl.GetFloatv\n#define glGetFragDataIndex                               gl3wProcs.gl.GetFragDataIndex\n#define glGetFragDataLocation                            gl3wProcs.gl.GetFragDataLocation\n#define glGetFramebufferAttachmentParameteriv            gl3wProcs.gl.GetFramebufferAttachmentParameteriv\n#define glGetFramebufferParameteriv                      gl3wProcs.gl.GetFramebufferParameteriv\n#define glGetFramebufferParameterivMESA                  gl3wProcs.gl.GetFramebufferParameterivMESA\n#define glGetGraphicsResetStatus                         gl3wProcs.gl.GetGraphicsResetStatus\n#define glGetInteger64i_v                                gl3wProcs.gl.GetInteger64i_v\n#define glGetInteger64v                                  gl3wProcs.gl.GetInteger64v\n#define glGetIntegeri_v                                  gl3wProcs.gl.GetIntegeri_v\n#define glGetIntegerv                                    gl3wProcs.gl.GetIntegerv\n#define glGetInternalformati64v                          gl3wProcs.gl.GetInternalformati64v\n#define glGetInternalformativ                            gl3wProcs.gl.GetInternalformativ\n#define glGetMultisamplefv                               gl3wProcs.gl.GetMultisamplefv\n#define glGetNamedBufferParameteri64v                    gl3wProcs.gl.GetNamedBufferParameteri64v\n#define glGetNamedBufferParameteriv                      gl3wProcs.gl.GetNamedBufferParameteriv\n#define glGetNamedBufferPointerv                         gl3wProcs.gl.GetNamedBufferPointerv\n#define glGetNamedBufferSubData                          gl3wProcs.gl.GetNamedBufferSubData\n#define glGetNamedFramebufferAttachmentParameteriv       gl3wProcs.gl.GetNamedFramebufferAttachmentParameteriv\n#define glGetNamedFramebufferParameteriv                 gl3wProcs.gl.GetNamedFramebufferParameteriv\n#define glGetNamedRenderbufferParameteriv                gl3wProcs.gl.GetNamedRenderbufferParameteriv\n#define glGetObjectLabel                                 gl3wProcs.gl.GetObjectLabel\n#define glGetObjectPtrLabel                              gl3wProcs.gl.GetObjectPtrLabel\n#define glGetPointerv                                    gl3wProcs.gl.GetPointerv\n#define glGetProgramBinary                               gl3wProcs.gl.GetProgramBinary\n#define glGetProgramInfoLog                              gl3wProcs.gl.GetProgramInfoLog\n#define glGetProgramInterfaceiv                          gl3wProcs.gl.GetProgramInterfaceiv\n#define glGetProgramPipelineInfoLog                      gl3wProcs.gl.GetProgramPipelineInfoLog\n#define glGetProgramPipelineiv                           gl3wProcs.gl.GetProgramPipelineiv\n#define glGetProgramResourceIndex                        gl3wProcs.gl.GetProgramResourceIndex\n#define glGetProgramResourceLocation                     gl3wProcs.gl.GetProgramResourceLocation\n#define glGetProgramResourceLocationIndex                gl3wProcs.gl.GetProgramResourceLocationIndex\n#define glGetProgramResourceName                         gl3wProcs.gl.GetProgramResourceName\n#define glGetProgramResourceiv                           gl3wProcs.gl.GetProgramResourceiv\n#define glGetProgramStageiv                              gl3wProcs.gl.GetProgramStageiv\n#define glGetProgramiv                                   gl3wProcs.gl.GetProgramiv\n#define glGetQueryBufferObjecti64v                       gl3wProcs.gl.GetQueryBufferObjecti64v\n#define glGetQueryBufferObjectiv                         gl3wProcs.gl.GetQueryBufferObjectiv\n#define glGetQueryBufferObjectui64v                      gl3wProcs.gl.GetQueryBufferObjectui64v\n#define glGetQueryBufferObjectuiv                        gl3wProcs.gl.GetQueryBufferObjectuiv\n#define glGetQueryIndexediv                              gl3wProcs.gl.GetQueryIndexediv\n#define glGetQueryObjecti64v                             gl3wProcs.gl.GetQueryObjecti64v\n#define glGetQueryObjectiv                               gl3wProcs.gl.GetQueryObjectiv\n#define glGetQueryObjectui64v                            gl3wProcs.gl.GetQueryObjectui64v\n#define glGetQueryObjectuiv                              gl3wProcs.gl.GetQueryObjectuiv\n#define glGetQueryiv                                     gl3wProcs.gl.GetQueryiv\n#define glGetRenderbufferParameteriv                     gl3wProcs.gl.GetRenderbufferParameteriv\n#define glGetSamplerParameterIiv                         gl3wProcs.gl.GetSamplerParameterIiv\n#define glGetSamplerParameterIuiv                        gl3wProcs.gl.GetSamplerParameterIuiv\n#define glGetSamplerParameterfv                          gl3wProcs.gl.GetSamplerParameterfv\n#define glGetSamplerParameteriv                          gl3wProcs.gl.GetSamplerParameteriv\n#define glGetShaderInfoLog                               gl3wProcs.gl.GetShaderInfoLog\n#define glGetShaderPrecisionFormat                       gl3wProcs.gl.GetShaderPrecisionFormat\n#define glGetShaderSource                                gl3wProcs.gl.GetShaderSource\n#define glGetShaderiv                                    gl3wProcs.gl.GetShaderiv\n#define glGetString                                      gl3wProcs.gl.GetString\n#define glGetStringi                                     gl3wProcs.gl.GetStringi\n#define glGetSubroutineIndex                             gl3wProcs.gl.GetSubroutineIndex\n#define glGetSubroutineUniformLocation                   gl3wProcs.gl.GetSubroutineUniformLocation\n#define glGetSynciv                                      gl3wProcs.gl.GetSynciv\n#define glGetTexImage                                    gl3wProcs.gl.GetTexImage\n#define glGetTexLevelParameterfv                         gl3wProcs.gl.GetTexLevelParameterfv\n#define glGetTexLevelParameteriv                         gl3wProcs.gl.GetTexLevelParameteriv\n#define glGetTexParameterIiv                             gl3wProcs.gl.GetTexParameterIiv\n#define glGetTexParameterIuiv                            gl3wProcs.gl.GetTexParameterIuiv\n#define glGetTexParameterfv                              gl3wProcs.gl.GetTexParameterfv\n#define glGetTexParameteriv                              gl3wProcs.gl.GetTexParameteriv\n#define glGetTextureImage                                gl3wProcs.gl.GetTextureImage\n#define glGetTextureLevelParameterfv                     gl3wProcs.gl.GetTextureLevelParameterfv\n#define glGetTextureLevelParameteriv                     gl3wProcs.gl.GetTextureLevelParameteriv\n#define glGetTextureParameterIiv                         gl3wProcs.gl.GetTextureParameterIiv\n#define glGetTextureParameterIuiv                        gl3wProcs.gl.GetTextureParameterIuiv\n#define glGetTextureParameterfv                          gl3wProcs.gl.GetTextureParameterfv\n#define glGetTextureParameteriv                          gl3wProcs.gl.GetTextureParameteriv\n#define glGetTextureSubImage                             gl3wProcs.gl.GetTextureSubImage\n#define glGetTransformFeedbackVarying                    gl3wProcs.gl.GetTransformFeedbackVarying\n#define glGetTransformFeedbacki64_v                      gl3wProcs.gl.GetTransformFeedbacki64_v\n#define glGetTransformFeedbacki_v                        gl3wProcs.gl.GetTransformFeedbacki_v\n#define glGetTransformFeedbackiv                         gl3wProcs.gl.GetTransformFeedbackiv\n#define glGetUniformBlockIndex                           gl3wProcs.gl.GetUniformBlockIndex\n#define glGetUniformIndices                              gl3wProcs.gl.GetUniformIndices\n#define glGetUniformLocation                             gl3wProcs.gl.GetUniformLocation\n#define glGetUniformSubroutineuiv                        gl3wProcs.gl.GetUniformSubroutineuiv\n#define glGetUniformdv                                   gl3wProcs.gl.GetUniformdv\n#define glGetUniformfv                                   gl3wProcs.gl.GetUniformfv\n#define glGetUniformiv                                   gl3wProcs.gl.GetUniformiv\n#define glGetUniformuiv                                  gl3wProcs.gl.GetUniformuiv\n#define glGetVertexArrayIndexed64iv                      gl3wProcs.gl.GetVertexArrayIndexed64iv\n#define glGetVertexArrayIndexediv                        gl3wProcs.gl.GetVertexArrayIndexediv\n#define glGetVertexArrayiv                               gl3wProcs.gl.GetVertexArrayiv\n#define glGetVertexAttribIiv                             gl3wProcs.gl.GetVertexAttribIiv\n#define glGetVertexAttribIuiv                            gl3wProcs.gl.GetVertexAttribIuiv\n#define glGetVertexAttribLdv                             gl3wProcs.gl.GetVertexAttribLdv\n#define glGetVertexAttribPointerv                        gl3wProcs.gl.GetVertexAttribPointerv\n#define glGetVertexAttribdv                              gl3wProcs.gl.GetVertexAttribdv\n#define glGetVertexAttribfv                              gl3wProcs.gl.GetVertexAttribfv\n#define glGetVertexAttribiv                              gl3wProcs.gl.GetVertexAttribiv\n#define glGetnCompressedTexImage                         gl3wProcs.gl.GetnCompressedTexImage\n#define glGetnTexImage                                   gl3wProcs.gl.GetnTexImage\n#define glGetnUniformdv                                  gl3wProcs.gl.GetnUniformdv\n#define glGetnUniformfv                                  gl3wProcs.gl.GetnUniformfv\n#define glGetnUniformiv                                  gl3wProcs.gl.GetnUniformiv\n#define glGetnUniformuiv                                 gl3wProcs.gl.GetnUniformuiv\n#define glHint                                           gl3wProcs.gl.Hint\n#define glInvalidateBufferData                           gl3wProcs.gl.InvalidateBufferData\n#define glInvalidateBufferSubData                        gl3wProcs.gl.InvalidateBufferSubData\n#define glInvalidateFramebuffer                          gl3wProcs.gl.InvalidateFramebuffer\n#define glInvalidateNamedFramebufferData                 gl3wProcs.gl.InvalidateNamedFramebufferData\n#define glInvalidateNamedFramebufferSubData              gl3wProcs.gl.InvalidateNamedFramebufferSubData\n#define glInvalidateSubFramebuffer                       gl3wProcs.gl.InvalidateSubFramebuffer\n#define glInvalidateTexImage                             gl3wProcs.gl.InvalidateTexImage\n#define glInvalidateTexSubImage                          gl3wProcs.gl.InvalidateTexSubImage\n#define glIsBuffer                                       gl3wProcs.gl.IsBuffer\n#define glIsEnabled                                      gl3wProcs.gl.IsEnabled\n#define glIsEnabledi                                     gl3wProcs.gl.IsEnabledi\n#define glIsFramebuffer                                  gl3wProcs.gl.IsFramebuffer\n#define glIsProgram                                      gl3wProcs.gl.IsProgram\n#define glIsProgramPipeline                              gl3wProcs.gl.IsProgramPipeline\n#define glIsQuery                                        gl3wProcs.gl.IsQuery\n#define glIsRenderbuffer                                 gl3wProcs.gl.IsRenderbuffer\n#define glIsSampler                                      gl3wProcs.gl.IsSampler\n#define glIsShader                                       gl3wProcs.gl.IsShader\n#define glIsSync                                         gl3wProcs.gl.IsSync\n#define glIsTexture                                      gl3wProcs.gl.IsTexture\n#define glIsTransformFeedback                            gl3wProcs.gl.IsTransformFeedback\n#define glIsVertexArray                                  gl3wProcs.gl.IsVertexArray\n#define glLineWidth                                      gl3wProcs.gl.LineWidth\n#define glLinkProgram                                    gl3wProcs.gl.LinkProgram\n#define glLogicOp                                        gl3wProcs.gl.LogicOp\n#define glMapBuffer                                      gl3wProcs.gl.MapBuffer\n#define glMapBufferRange                                 gl3wProcs.gl.MapBufferRange\n#define glMapNamedBuffer                                 gl3wProcs.gl.MapNamedBuffer\n#define glMapNamedBufferRange                            gl3wProcs.gl.MapNamedBufferRange\n#define glMemoryBarrier                                  gl3wProcs.gl.MemoryBarrier\n#define glMemoryBarrierByRegion                          gl3wProcs.gl.MemoryBarrierByRegion\n#define glMinSampleShading                               gl3wProcs.gl.MinSampleShading\n#define glMultiDrawArrays                                gl3wProcs.gl.MultiDrawArrays\n#define glMultiDrawArraysIndirect                        gl3wProcs.gl.MultiDrawArraysIndirect\n#define glMultiDrawArraysIndirectCount                   gl3wProcs.gl.MultiDrawArraysIndirectCount\n#define glMultiDrawElements                              gl3wProcs.gl.MultiDrawElements\n#define glMultiDrawElementsBaseVertex                    gl3wProcs.gl.MultiDrawElementsBaseVertex\n#define glMultiDrawElementsIndirect                      gl3wProcs.gl.MultiDrawElementsIndirect\n#define glMultiDrawElementsIndirectCount                 gl3wProcs.gl.MultiDrawElementsIndirectCount\n#define glNamedBufferData                                gl3wProcs.gl.NamedBufferData\n#define glNamedBufferStorage                             gl3wProcs.gl.NamedBufferStorage\n#define glNamedBufferSubData                             gl3wProcs.gl.NamedBufferSubData\n#define glNamedFramebufferDrawBuffer                     gl3wProcs.gl.NamedFramebufferDrawBuffer\n#define glNamedFramebufferDrawBuffers                    gl3wProcs.gl.NamedFramebufferDrawBuffers\n#define glNamedFramebufferParameteri                     gl3wProcs.gl.NamedFramebufferParameteri\n#define glNamedFramebufferReadBuffer                     gl3wProcs.gl.NamedFramebufferReadBuffer\n#define glNamedFramebufferRenderbuffer                   gl3wProcs.gl.NamedFramebufferRenderbuffer\n#define glNamedFramebufferTexture                        gl3wProcs.gl.NamedFramebufferTexture\n#define glNamedFramebufferTextureLayer                   gl3wProcs.gl.NamedFramebufferTextureLayer\n#define glNamedRenderbufferStorage                       gl3wProcs.gl.NamedRenderbufferStorage\n#define glNamedRenderbufferStorageMultisample            gl3wProcs.gl.NamedRenderbufferStorageMultisample\n#define glObjectLabel                                    gl3wProcs.gl.ObjectLabel\n#define glObjectPtrLabel                                 gl3wProcs.gl.ObjectPtrLabel\n#define glPatchParameterfv                               gl3wProcs.gl.PatchParameterfv\n#define glPatchParameteri                                gl3wProcs.gl.PatchParameteri\n#define glPauseTransformFeedback                         gl3wProcs.gl.PauseTransformFeedback\n#define glPixelStoref                                    gl3wProcs.gl.PixelStoref\n#define glPixelStorei                                    gl3wProcs.gl.PixelStorei\n#define glPointParameterf                                gl3wProcs.gl.PointParameterf\n#define glPointParameterfv                               gl3wProcs.gl.PointParameterfv\n#define glPointParameteri                                gl3wProcs.gl.PointParameteri\n#define glPointParameteriv                               gl3wProcs.gl.PointParameteriv\n#define glPointSize                                      gl3wProcs.gl.PointSize\n#define glPolygonMode                                    gl3wProcs.gl.PolygonMode\n#define glPolygonOffset                                  gl3wProcs.gl.PolygonOffset\n#define glPolygonOffsetClamp                             gl3wProcs.gl.PolygonOffsetClamp\n#define glPopDebugGroup                                  gl3wProcs.gl.PopDebugGroup\n#define glPrimitiveRestartIndex                          gl3wProcs.gl.PrimitiveRestartIndex\n#define glProgramBinary                                  gl3wProcs.gl.ProgramBinary\n#define glProgramParameteri                              gl3wProcs.gl.ProgramParameteri\n#define glProgramUniform1d                               gl3wProcs.gl.ProgramUniform1d\n#define glProgramUniform1dv                              gl3wProcs.gl.ProgramUniform1dv\n#define glProgramUniform1f                               gl3wProcs.gl.ProgramUniform1f\n#define glProgramUniform1fv                              gl3wProcs.gl.ProgramUniform1fv\n#define glProgramUniform1i                               gl3wProcs.gl.ProgramUniform1i\n#define glProgramUniform1iv                              gl3wProcs.gl.ProgramUniform1iv\n#define glProgramUniform1ui                              gl3wProcs.gl.ProgramUniform1ui\n#define glProgramUniform1uiv                             gl3wProcs.gl.ProgramUniform1uiv\n#define glProgramUniform2d                               gl3wProcs.gl.ProgramUniform2d\n#define glProgramUniform2dv                              gl3wProcs.gl.ProgramUniform2dv\n#define glProgramUniform2f                               gl3wProcs.gl.ProgramUniform2f\n#define glProgramUniform2fv                              gl3wProcs.gl.ProgramUniform2fv\n#define glProgramUniform2i                               gl3wProcs.gl.ProgramUniform2i\n#define glProgramUniform2iv                              gl3wProcs.gl.ProgramUniform2iv\n#define glProgramUniform2ui                              gl3wProcs.gl.ProgramUniform2ui\n#define glProgramUniform2uiv                             gl3wProcs.gl.ProgramUniform2uiv\n#define glProgramUniform3d                               gl3wProcs.gl.ProgramUniform3d\n#define glProgramUniform3dv                              gl3wProcs.gl.ProgramUniform3dv\n#define glProgramUniform3f                               gl3wProcs.gl.ProgramUniform3f\n#define glProgramUniform3fv                              gl3wProcs.gl.ProgramUniform3fv\n#define glProgramUniform3i                               gl3wProcs.gl.ProgramUniform3i\n#define glProgramUniform3iv                              gl3wProcs.gl.ProgramUniform3iv\n#define glProgramUniform3ui                              gl3wProcs.gl.ProgramUniform3ui\n#define glProgramUniform3uiv                             gl3wProcs.gl.ProgramUniform3uiv\n#define glProgramUniform4d                               gl3wProcs.gl.ProgramUniform4d\n#define glProgramUniform4dv                              gl3wProcs.gl.ProgramUniform4dv\n#define glProgramUniform4f                               gl3wProcs.gl.ProgramUniform4f\n#define glProgramUniform4fv                              gl3wProcs.gl.ProgramUniform4fv\n#define glProgramUniform4i                               gl3wProcs.gl.ProgramUniform4i\n#define glProgramUniform4iv                              gl3wProcs.gl.ProgramUniform4iv\n#define glProgramUniform4ui                              gl3wProcs.gl.ProgramUniform4ui\n#define glProgramUniform4uiv                             gl3wProcs.gl.ProgramUniform4uiv\n#define glProgramUniformMatrix2dv                        gl3wProcs.gl.ProgramUniformMatrix2dv\n#define glProgramUniformMatrix2fv                        gl3wProcs.gl.ProgramUniformMatrix2fv\n#define glProgramUniformMatrix2x3dv                      gl3wProcs.gl.ProgramUniformMatrix2x3dv\n#define glProgramUniformMatrix2x3fv                      gl3wProcs.gl.ProgramUniformMatrix2x3fv\n#define glProgramUniformMatrix2x4dv                      gl3wProcs.gl.ProgramUniformMatrix2x4dv\n#define glProgramUniformMatrix2x4fv                      gl3wProcs.gl.ProgramUniformMatrix2x4fv\n#define glProgramUniformMatrix3dv                        gl3wProcs.gl.ProgramUniformMatrix3dv\n#define glProgramUniformMatrix3fv                        gl3wProcs.gl.ProgramUniformMatrix3fv\n#define glProgramUniformMatrix3x2dv                      gl3wProcs.gl.ProgramUniformMatrix3x2dv\n#define glProgramUniformMatrix3x2fv                      gl3wProcs.gl.ProgramUniformMatrix3x2fv\n#define glProgramUniformMatrix3x4dv                      gl3wProcs.gl.ProgramUniformMatrix3x4dv\n#define glProgramUniformMatrix3x4fv                      gl3wProcs.gl.ProgramUniformMatrix3x4fv\n#define glProgramUniformMatrix4dv                        gl3wProcs.gl.ProgramUniformMatrix4dv\n#define glProgramUniformMatrix4fv                        gl3wProcs.gl.ProgramUniformMatrix4fv\n#define glProgramUniformMatrix4x2dv                      gl3wProcs.gl.ProgramUniformMatrix4x2dv\n#define glProgramUniformMatrix4x2fv                      gl3wProcs.gl.ProgramUniformMatrix4x2fv\n#define glProgramUniformMatrix4x3dv                      gl3wProcs.gl.ProgramUniformMatrix4x3dv\n#define glProgramUniformMatrix4x3fv                      gl3wProcs.gl.ProgramUniformMatrix4x3fv\n#define glProvokingVertex                                gl3wProcs.gl.ProvokingVertex\n#define glPushDebugGroup                                 gl3wProcs.gl.PushDebugGroup\n#define glQueryCounter                                   gl3wProcs.gl.QueryCounter\n#define glReadBuffer                                     gl3wProcs.gl.ReadBuffer\n#define glReadPixels                                     gl3wProcs.gl.ReadPixels\n#define glReadnPixels                                    gl3wProcs.gl.ReadnPixels\n#define glReleaseShaderCompiler                          gl3wProcs.gl.ReleaseShaderCompiler\n#define glRenderbufferStorage                            gl3wProcs.gl.RenderbufferStorage\n#define glRenderbufferStorageMultisample                 gl3wProcs.gl.RenderbufferStorageMultisample\n#define glResumeTransformFeedback                        gl3wProcs.gl.ResumeTransformFeedback\n#define glSampleCoverage                                 gl3wProcs.gl.SampleCoverage\n#define glSampleMaski                                    gl3wProcs.gl.SampleMaski\n#define glSamplerParameterIiv                            gl3wProcs.gl.SamplerParameterIiv\n#define glSamplerParameterIuiv                           gl3wProcs.gl.SamplerParameterIuiv\n#define glSamplerParameterf                              gl3wProcs.gl.SamplerParameterf\n#define glSamplerParameterfv                             gl3wProcs.gl.SamplerParameterfv\n#define glSamplerParameteri                              gl3wProcs.gl.SamplerParameteri\n#define glSamplerParameteriv                             gl3wProcs.gl.SamplerParameteriv\n#define glScissor                                        gl3wProcs.gl.Scissor\n#define glScissorArrayv                                  gl3wProcs.gl.ScissorArrayv\n#define glScissorIndexed                                 gl3wProcs.gl.ScissorIndexed\n#define glScissorIndexedv                                gl3wProcs.gl.ScissorIndexedv\n#define glShaderBinary                                   gl3wProcs.gl.ShaderBinary\n#define glShaderSource                                   gl3wProcs.gl.ShaderSource\n#define glShaderStorageBlockBinding                      gl3wProcs.gl.ShaderStorageBlockBinding\n#define glSpecializeShader                               gl3wProcs.gl.SpecializeShader\n#define glStencilFunc                                    gl3wProcs.gl.StencilFunc\n#define glStencilFuncSeparate                            gl3wProcs.gl.StencilFuncSeparate\n#define glStencilMask                                    gl3wProcs.gl.StencilMask\n#define glStencilMaskSeparate                            gl3wProcs.gl.StencilMaskSeparate\n#define glStencilOp                                      gl3wProcs.gl.StencilOp\n#define glStencilOpSeparate                              gl3wProcs.gl.StencilOpSeparate\n#define glTexBuffer                                      gl3wProcs.gl.TexBuffer\n#define glTexBufferRange                                 gl3wProcs.gl.TexBufferRange\n#define glTexImage1D                                     gl3wProcs.gl.TexImage1D\n#define glTexImage2D                                     gl3wProcs.gl.TexImage2D\n#define glTexImage2DMultisample                          gl3wProcs.gl.TexImage2DMultisample\n#define glTexImage3D                                     gl3wProcs.gl.TexImage3D\n#define glTexImage3DMultisample                          gl3wProcs.gl.TexImage3DMultisample\n#define glTexParameterIiv                                gl3wProcs.gl.TexParameterIiv\n#define glTexParameterIuiv                               gl3wProcs.gl.TexParameterIuiv\n#define glTexParameterf                                  gl3wProcs.gl.TexParameterf\n#define glTexParameterfv                                 gl3wProcs.gl.TexParameterfv\n#define glTexParameteri                                  gl3wProcs.gl.TexParameteri\n#define glTexParameteriv                                 gl3wProcs.gl.TexParameteriv\n#define glTexStorage1D                                   gl3wProcs.gl.TexStorage1D\n#define glTexStorage2D                                   gl3wProcs.gl.TexStorage2D\n#define glTexStorage2DMultisample                        gl3wProcs.gl.TexStorage2DMultisample\n#define glTexStorage3D                                   gl3wProcs.gl.TexStorage3D\n#define glTexStorage3DMultisample                        gl3wProcs.gl.TexStorage3DMultisample\n#define glTexSubImage1D                                  gl3wProcs.gl.TexSubImage1D\n#define glTexSubImage2D                                  gl3wProcs.gl.TexSubImage2D\n#define glTexSubImage3D                                  gl3wProcs.gl.TexSubImage3D\n#define glTextureBarrier                                 gl3wProcs.gl.TextureBarrier\n#define glTextureBuffer                                  gl3wProcs.gl.TextureBuffer\n#define glTextureBufferRange                             gl3wProcs.gl.TextureBufferRange\n#define glTextureParameterIiv                            gl3wProcs.gl.TextureParameterIiv\n#define glTextureParameterIuiv                           gl3wProcs.gl.TextureParameterIuiv\n#define glTextureParameterf                              gl3wProcs.gl.TextureParameterf\n#define glTextureParameterfv                             gl3wProcs.gl.TextureParameterfv\n#define glTextureParameteri                              gl3wProcs.gl.TextureParameteri\n#define glTextureParameteriv                             gl3wProcs.gl.TextureParameteriv\n#define glTextureStorage1D                               gl3wProcs.gl.TextureStorage1D\n#define glTextureStorage2D                               gl3wProcs.gl.TextureStorage2D\n#define glTextureStorage2DMultisample                    gl3wProcs.gl.TextureStorage2DMultisample\n#define glTextureStorage3D                               gl3wProcs.gl.TextureStorage3D\n#define glTextureStorage3DMultisample                    gl3wProcs.gl.TextureStorage3DMultisample\n#define glTextureSubImage1D                              gl3wProcs.gl.TextureSubImage1D\n#define glTextureSubImage2D                              gl3wProcs.gl.TextureSubImage2D\n#define glTextureSubImage3D                              gl3wProcs.gl.TextureSubImage3D\n#define glTextureView                                    gl3wProcs.gl.TextureView\n#define glTransformFeedbackBufferBase                    gl3wProcs.gl.TransformFeedbackBufferBase\n#define glTransformFeedbackBufferRange                   gl3wProcs.gl.TransformFeedbackBufferRange\n#define glTransformFeedbackVaryings                      gl3wProcs.gl.TransformFeedbackVaryings\n#define glUniform1d                                      gl3wProcs.gl.Uniform1d\n#define glUniform1dv                                     gl3wProcs.gl.Uniform1dv\n#define glUniform1f                                      gl3wProcs.gl.Uniform1f\n#define glUniform1fv                                     gl3wProcs.gl.Uniform1fv\n#define glUniform1i                                      gl3wProcs.gl.Uniform1i\n#define glUniform1iv                                     gl3wProcs.gl.Uniform1iv\n#define glUniform1ui                                     gl3wProcs.gl.Uniform1ui\n#define glUniform1uiv                                    gl3wProcs.gl.Uniform1uiv\n#define glUniform2d                                      gl3wProcs.gl.Uniform2d\n#define glUniform2dv                                     gl3wProcs.gl.Uniform2dv\n#define glUniform2f                                      gl3wProcs.gl.Uniform2f\n#define glUniform2fv                                     gl3wProcs.gl.Uniform2fv\n#define glUniform2i                                      gl3wProcs.gl.Uniform2i\n#define glUniform2iv                                     gl3wProcs.gl.Uniform2iv\n#define glUniform2ui                                     gl3wProcs.gl.Uniform2ui\n#define glUniform2uiv                                    gl3wProcs.gl.Uniform2uiv\n#define glUniform3d                                      gl3wProcs.gl.Uniform3d\n#define glUniform3dv                                     gl3wProcs.gl.Uniform3dv\n#define glUniform3f                                      gl3wProcs.gl.Uniform3f\n#define glUniform3fv                                     gl3wProcs.gl.Uniform3fv\n#define glUniform3i                                      gl3wProcs.gl.Uniform3i\n#define glUniform3iv                                     gl3wProcs.gl.Uniform3iv\n#define glUniform3ui                                     gl3wProcs.gl.Uniform3ui\n#define glUniform3uiv                                    gl3wProcs.gl.Uniform3uiv\n#define glUniform4d                                      gl3wProcs.gl.Uniform4d\n#define glUniform4dv                                     gl3wProcs.gl.Uniform4dv\n#define glUniform4f                                      gl3wProcs.gl.Uniform4f\n#define glUniform4fv                                     gl3wProcs.gl.Uniform4fv\n#define glUniform4i                                      gl3wProcs.gl.Uniform4i\n#define glUniform4iv                                     gl3wProcs.gl.Uniform4iv\n#define glUniform4ui                                     gl3wProcs.gl.Uniform4ui\n#define glUniform4uiv                                    gl3wProcs.gl.Uniform4uiv\n#define glUniformBlockBinding                            gl3wProcs.gl.UniformBlockBinding\n#define glUniformMatrix2dv                               gl3wProcs.gl.UniformMatrix2dv\n#define glUniformMatrix2fv                               gl3wProcs.gl.UniformMatrix2fv\n#define glUniformMatrix2x3dv                             gl3wProcs.gl.UniformMatrix2x3dv\n#define glUniformMatrix2x3fv                             gl3wProcs.gl.UniformMatrix2x3fv\n#define glUniformMatrix2x4dv                             gl3wProcs.gl.UniformMatrix2x4dv\n#define glUniformMatrix2x4fv                             gl3wProcs.gl.UniformMatrix2x4fv\n#define glUniformMatrix3dv                               gl3wProcs.gl.UniformMatrix3dv\n#define glUniformMatrix3fv                               gl3wProcs.gl.UniformMatrix3fv\n#define glUniformMatrix3x2dv                             gl3wProcs.gl.UniformMatrix3x2dv\n#define glUniformMatrix3x2fv                             gl3wProcs.gl.UniformMatrix3x2fv\n#define glUniformMatrix3x4dv                             gl3wProcs.gl.UniformMatrix3x4dv\n#define glUniformMatrix3x4fv                             gl3wProcs.gl.UniformMatrix3x4fv\n#define glUniformMatrix4dv                               gl3wProcs.gl.UniformMatrix4dv\n#define glUniformMatrix4fv                               gl3wProcs.gl.UniformMatrix4fv\n#define glUniformMatrix4x2dv                             gl3wProcs.gl.UniformMatrix4x2dv\n#define glUniformMatrix4x2fv                             gl3wProcs.gl.UniformMatrix4x2fv\n#define glUniformMatrix4x3dv                             gl3wProcs.gl.UniformMatrix4x3dv\n#define glUniformMatrix4x3fv                             gl3wProcs.gl.UniformMatrix4x3fv\n#define glUniformSubroutinesuiv                          gl3wProcs.gl.UniformSubroutinesuiv\n#define glUnmapBuffer                                    gl3wProcs.gl.UnmapBuffer\n#define glUnmapNamedBuffer                               gl3wProcs.gl.UnmapNamedBuffer\n#define glUseProgram                                     gl3wProcs.gl.UseProgram\n#define glUseProgramStages                               gl3wProcs.gl.UseProgramStages\n#define glValidateProgram                                gl3wProcs.gl.ValidateProgram\n#define glValidateProgramPipeline                        gl3wProcs.gl.ValidateProgramPipeline\n#define glVertexArrayAttribBinding                       gl3wProcs.gl.VertexArrayAttribBinding\n#define glVertexArrayAttribFormat                        gl3wProcs.gl.VertexArrayAttribFormat\n#define glVertexArrayAttribIFormat                       gl3wProcs.gl.VertexArrayAttribIFormat\n#define glVertexArrayAttribLFormat                       gl3wProcs.gl.VertexArrayAttribLFormat\n#define glVertexArrayBindingDivisor                      gl3wProcs.gl.VertexArrayBindingDivisor\n#define glVertexArrayElementBuffer                       gl3wProcs.gl.VertexArrayElementBuffer\n#define glVertexArrayVertexBuffer                        gl3wProcs.gl.VertexArrayVertexBuffer\n#define glVertexArrayVertexBuffers                       gl3wProcs.gl.VertexArrayVertexBuffers\n#define glVertexAttrib1d                                 gl3wProcs.gl.VertexAttrib1d\n#define glVertexAttrib1dv                                gl3wProcs.gl.VertexAttrib1dv\n#define glVertexAttrib1f                                 gl3wProcs.gl.VertexAttrib1f\n#define glVertexAttrib1fv                                gl3wProcs.gl.VertexAttrib1fv\n#define glVertexAttrib1s                                 gl3wProcs.gl.VertexAttrib1s\n#define glVertexAttrib1sv                                gl3wProcs.gl.VertexAttrib1sv\n#define glVertexAttrib2d                                 gl3wProcs.gl.VertexAttrib2d\n#define glVertexAttrib2dv                                gl3wProcs.gl.VertexAttrib2dv\n#define glVertexAttrib2f                                 gl3wProcs.gl.VertexAttrib2f\n#define glVertexAttrib2fv                                gl3wProcs.gl.VertexAttrib2fv\n#define glVertexAttrib2s                                 gl3wProcs.gl.VertexAttrib2s\n#define glVertexAttrib2sv                                gl3wProcs.gl.VertexAttrib2sv\n#define glVertexAttrib3d                                 gl3wProcs.gl.VertexAttrib3d\n#define glVertexAttrib3dv                                gl3wProcs.gl.VertexAttrib3dv\n#define glVertexAttrib3f                                 gl3wProcs.gl.VertexAttrib3f\n#define glVertexAttrib3fv                                gl3wProcs.gl.VertexAttrib3fv\n#define glVertexAttrib3s                                 gl3wProcs.gl.VertexAttrib3s\n#define glVertexAttrib3sv                                gl3wProcs.gl.VertexAttrib3sv\n#define glVertexAttrib4Nbv                               gl3wProcs.gl.VertexAttrib4Nbv\n#define glVertexAttrib4Niv                               gl3wProcs.gl.VertexAttrib4Niv\n#define glVertexAttrib4Nsv                               gl3wProcs.gl.VertexAttrib4Nsv\n#define glVertexAttrib4Nub                               gl3wProcs.gl.VertexAttrib4Nub\n#define glVertexAttrib4Nubv                              gl3wProcs.gl.VertexAttrib4Nubv\n#define glVertexAttrib4Nuiv                              gl3wProcs.gl.VertexAttrib4Nuiv\n#define glVertexAttrib4Nusv                              gl3wProcs.gl.VertexAttrib4Nusv\n#define glVertexAttrib4bv                                gl3wProcs.gl.VertexAttrib4bv\n#define glVertexAttrib4d                                 gl3wProcs.gl.VertexAttrib4d\n#define glVertexAttrib4dv                                gl3wProcs.gl.VertexAttrib4dv\n#define glVertexAttrib4f                                 gl3wProcs.gl.VertexAttrib4f\n#define glVertexAttrib4fv                                gl3wProcs.gl.VertexAttrib4fv\n#define glVertexAttrib4iv                                gl3wProcs.gl.VertexAttrib4iv\n#define glVertexAttrib4s                                 gl3wProcs.gl.VertexAttrib4s\n#define glVertexAttrib4sv                                gl3wProcs.gl.VertexAttrib4sv\n#define glVertexAttrib4ubv                               gl3wProcs.gl.VertexAttrib4ubv\n#define glVertexAttrib4uiv                               gl3wProcs.gl.VertexAttrib4uiv\n#define glVertexAttrib4usv                               gl3wProcs.gl.VertexAttrib4usv\n#define glVertexAttribBinding                            gl3wProcs.gl.VertexAttribBinding\n#define glVertexAttribDivisor                            gl3wProcs.gl.VertexAttribDivisor\n#define glVertexAttribFormat                             gl3wProcs.gl.VertexAttribFormat\n#define glVertexAttribI1i                                gl3wProcs.gl.VertexAttribI1i\n#define glVertexAttribI1iv                               gl3wProcs.gl.VertexAttribI1iv\n#define glVertexAttribI1ui                               gl3wProcs.gl.VertexAttribI1ui\n#define glVertexAttribI1uiv                              gl3wProcs.gl.VertexAttribI1uiv\n#define glVertexAttribI2i                                gl3wProcs.gl.VertexAttribI2i\n#define glVertexAttribI2iv                               gl3wProcs.gl.VertexAttribI2iv\n#define glVertexAttribI2ui                               gl3wProcs.gl.VertexAttribI2ui\n#define glVertexAttribI2uiv                              gl3wProcs.gl.VertexAttribI2uiv\n#define glVertexAttribI3i                                gl3wProcs.gl.VertexAttribI3i\n#define glVertexAttribI3iv                               gl3wProcs.gl.VertexAttribI3iv\n#define glVertexAttribI3ui                               gl3wProcs.gl.VertexAttribI3ui\n#define glVertexAttribI3uiv                              gl3wProcs.gl.VertexAttribI3uiv\n#define glVertexAttribI4bv                               gl3wProcs.gl.VertexAttribI4bv\n#define glVertexAttribI4i                                gl3wProcs.gl.VertexAttribI4i\n#define glVertexAttribI4iv                               gl3wProcs.gl.VertexAttribI4iv\n#define glVertexAttribI4sv                               gl3wProcs.gl.VertexAttribI4sv\n#define glVertexAttribI4ubv                              gl3wProcs.gl.VertexAttribI4ubv\n#define glVertexAttribI4ui                               gl3wProcs.gl.VertexAttribI4ui\n#define glVertexAttribI4uiv                              gl3wProcs.gl.VertexAttribI4uiv\n#define glVertexAttribI4usv                              gl3wProcs.gl.VertexAttribI4usv\n#define glVertexAttribIFormat                            gl3wProcs.gl.VertexAttribIFormat\n#define glVertexAttribIPointer                           gl3wProcs.gl.VertexAttribIPointer\n#define glVertexAttribL1d                                gl3wProcs.gl.VertexAttribL1d\n#define glVertexAttribL1dv                               gl3wProcs.gl.VertexAttribL1dv\n#define glVertexAttribL2d                                gl3wProcs.gl.VertexAttribL2d\n#define glVertexAttribL2dv                               gl3wProcs.gl.VertexAttribL2dv\n#define glVertexAttribL3d                                gl3wProcs.gl.VertexAttribL3d\n#define glVertexAttribL3dv                               gl3wProcs.gl.VertexAttribL3dv\n#define glVertexAttribL4d                                gl3wProcs.gl.VertexAttribL4d\n#define glVertexAttribL4dv                               gl3wProcs.gl.VertexAttribL4dv\n#define glVertexAttribLFormat                            gl3wProcs.gl.VertexAttribLFormat\n#define glVertexAttribLPointer                           gl3wProcs.gl.VertexAttribLPointer\n#define glVertexAttribP1ui                               gl3wProcs.gl.VertexAttribP1ui\n#define glVertexAttribP1uiv                              gl3wProcs.gl.VertexAttribP1uiv\n#define glVertexAttribP2ui                               gl3wProcs.gl.VertexAttribP2ui\n#define glVertexAttribP2uiv                              gl3wProcs.gl.VertexAttribP2uiv\n#define glVertexAttribP3ui                               gl3wProcs.gl.VertexAttribP3ui\n#define glVertexAttribP3uiv                              gl3wProcs.gl.VertexAttribP3uiv\n#define glVertexAttribP4ui                               gl3wProcs.gl.VertexAttribP4ui\n#define glVertexAttribP4uiv                              gl3wProcs.gl.VertexAttribP4uiv\n#define glVertexAttribPointer                            gl3wProcs.gl.VertexAttribPointer\n#define glVertexBindingDivisor                           gl3wProcs.gl.VertexBindingDivisor\n#define glViewport                                       gl3wProcs.gl.Viewport\n#define glViewportArrayv                                 gl3wProcs.gl.ViewportArrayv\n#define glViewportIndexedf                               gl3wProcs.gl.ViewportIndexedf\n#define glViewportIndexedfv                              gl3wProcs.gl.ViewportIndexedfv\n#define glWaitSync                                       gl3wProcs.gl.WaitSync\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "external/include/GL/glcorearb.h",
    "content": "#ifndef __gl_glcorearb_h_\n#define __gl_glcorearb_h_ 1\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*\n** Copyright 2013-2020 The Khronos Group Inc.\n** SPDX-License-Identifier: MIT\n**\n** This header is generated from the Khronos OpenGL / OpenGL ES XML\n** API Registry. The current version of the Registry, generator scripts\n** used to make the header, and the header can be found at\n**   https://github.com/KhronosGroup/OpenGL-Registry\n*/\n\n#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN 1\n#endif\n#include <windows.h>\n#endif\n\n#ifndef APIENTRY\n#define APIENTRY\n#endif\n#ifndef APIENTRYP\n#define APIENTRYP APIENTRY *\n#endif\n#ifndef GLAPI\n#define GLAPI extern\n#endif\n\n/* glcorearb.h is for use with OpenGL core profile implementations.\n** It should should be placed in the same directory as gl.h and\n** included as <GL/glcorearb.h>.\n**\n** glcorearb.h includes only APIs in the latest OpenGL core profile\n** implementation together with APIs in newer ARB extensions which \n** can be supported by the core profile. It does not, and never will\n** include functionality removed from the core profile, such as\n** fixed-function vertex and fragment processing.\n**\n** Do not #include both <GL/glcorearb.h> and either of <GL/gl.h> or\n** <GL/glext.h> in the same source file.\n*/\n\n/* Generated C header for:\n * API: gl\n * Profile: core\n * Versions considered: .*\n * Versions emitted: .*\n * Default extensions included: glcore\n * Additional extensions included: _nomatch_^\n * Extensions removed: _nomatch_^\n */\n\n#ifndef GL_VERSION_1_0\n#define GL_VERSION_1_0 1\ntypedef void GLvoid;\ntypedef unsigned int GLenum;\n#include <KHR/khrplatform.h>\ntypedef khronos_float_t GLfloat;\ntypedef int GLint;\ntypedef int GLsizei;\ntypedef unsigned int GLbitfield;\ntypedef double GLdouble;\ntypedef unsigned int GLuint;\ntypedef unsigned char GLboolean;\ntypedef khronos_uint8_t GLubyte;\n#define GL_DEPTH_BUFFER_BIT               0x00000100\n#define GL_STENCIL_BUFFER_BIT             0x00000400\n#define GL_COLOR_BUFFER_BIT               0x00004000\n#define GL_FALSE                          0\n#define GL_TRUE                           1\n#define GL_POINTS                         0x0000\n#define GL_LINES                          0x0001\n#define GL_LINE_LOOP                      0x0002\n#define GL_LINE_STRIP                     0x0003\n#define GL_TRIANGLES                      0x0004\n#define GL_TRIANGLE_STRIP                 0x0005\n#define GL_TRIANGLE_FAN                   0x0006\n#define GL_QUADS                          0x0007\n#define GL_NEVER                          0x0200\n#define GL_LESS                           0x0201\n#define GL_EQUAL                          0x0202\n#define GL_LEQUAL                         0x0203\n#define GL_GREATER                        0x0204\n#define GL_NOTEQUAL                       0x0205\n#define GL_GEQUAL                         0x0206\n#define GL_ALWAYS                         0x0207\n#define GL_ZERO                           0\n#define GL_ONE                            1\n#define GL_SRC_COLOR                      0x0300\n#define GL_ONE_MINUS_SRC_COLOR            0x0301\n#define GL_SRC_ALPHA                      0x0302\n#define GL_ONE_MINUS_SRC_ALPHA            0x0303\n#define GL_DST_ALPHA                      0x0304\n#define GL_ONE_MINUS_DST_ALPHA            0x0305\n#define GL_DST_COLOR                      0x0306\n#define GL_ONE_MINUS_DST_COLOR            0x0307\n#define GL_SRC_ALPHA_SATURATE             0x0308\n#define GL_NONE                           0\n#define GL_FRONT_LEFT                     0x0400\n#define GL_FRONT_RIGHT                    0x0401\n#define GL_BACK_LEFT                      0x0402\n#define GL_BACK_RIGHT                     0x0403\n#define GL_FRONT                          0x0404\n#define GL_BACK                           0x0405\n#define GL_LEFT                           0x0406\n#define GL_RIGHT                          0x0407\n#define GL_FRONT_AND_BACK                 0x0408\n#define GL_NO_ERROR                       0\n#define GL_INVALID_ENUM                   0x0500\n#define GL_INVALID_VALUE                  0x0501\n#define GL_INVALID_OPERATION              0x0502\n#define GL_OUT_OF_MEMORY                  0x0505\n#define GL_CW                             0x0900\n#define GL_CCW                            0x0901\n#define GL_POINT_SIZE                     0x0B11\n#define GL_POINT_SIZE_RANGE               0x0B12\n#define GL_POINT_SIZE_GRANULARITY         0x0B13\n#define GL_LINE_SMOOTH                    0x0B20\n#define GL_LINE_WIDTH                     0x0B21\n#define GL_LINE_WIDTH_RANGE               0x0B22\n#define GL_LINE_WIDTH_GRANULARITY         0x0B23\n#define GL_POLYGON_MODE                   0x0B40\n#define GL_POLYGON_SMOOTH                 0x0B41\n#define GL_CULL_FACE                      0x0B44\n#define GL_CULL_FACE_MODE                 0x0B45\n#define GL_FRONT_FACE                     0x0B46\n#define GL_DEPTH_RANGE                    0x0B70\n#define GL_DEPTH_TEST                     0x0B71\n#define GL_DEPTH_WRITEMASK                0x0B72\n#define GL_DEPTH_CLEAR_VALUE              0x0B73\n#define GL_DEPTH_FUNC                     0x0B74\n#define GL_STENCIL_TEST                   0x0B90\n#define GL_STENCIL_CLEAR_VALUE            0x0B91\n#define GL_STENCIL_FUNC                   0x0B92\n#define GL_STENCIL_VALUE_MASK             0x0B93\n#define GL_STENCIL_FAIL                   0x0B94\n#define GL_STENCIL_PASS_DEPTH_FAIL        0x0B95\n#define GL_STENCIL_PASS_DEPTH_PASS        0x0B96\n#define GL_STENCIL_REF                    0x0B97\n#define GL_STENCIL_WRITEMASK              0x0B98\n#define GL_VIEWPORT                       0x0BA2\n#define GL_DITHER                         0x0BD0\n#define GL_BLEND_DST                      0x0BE0\n#define GL_BLEND_SRC                      0x0BE1\n#define GL_BLEND                          0x0BE2\n#define GL_LOGIC_OP_MODE                  0x0BF0\n#define GL_DRAW_BUFFER                    0x0C01\n#define GL_READ_BUFFER                    0x0C02\n#define GL_SCISSOR_BOX                    0x0C10\n#define GL_SCISSOR_TEST                   0x0C11\n#define GL_COLOR_CLEAR_VALUE              0x0C22\n#define GL_COLOR_WRITEMASK                0x0C23\n#define GL_DOUBLEBUFFER                   0x0C32\n#define GL_STEREO                         0x0C33\n#define GL_LINE_SMOOTH_HINT               0x0C52\n#define GL_POLYGON_SMOOTH_HINT            0x0C53\n#define GL_UNPACK_SWAP_BYTES              0x0CF0\n#define GL_UNPACK_LSB_FIRST               0x0CF1\n#define GL_UNPACK_ROW_LENGTH              0x0CF2\n#define GL_UNPACK_SKIP_ROWS               0x0CF3\n#define GL_UNPACK_SKIP_PIXELS             0x0CF4\n#define GL_UNPACK_ALIGNMENT               0x0CF5\n#define GL_PACK_SWAP_BYTES                0x0D00\n#define GL_PACK_LSB_FIRST                 0x0D01\n#define GL_PACK_ROW_LENGTH                0x0D02\n#define GL_PACK_SKIP_ROWS                 0x0D03\n#define GL_PACK_SKIP_PIXELS               0x0D04\n#define GL_PACK_ALIGNMENT                 0x0D05\n#define GL_MAX_TEXTURE_SIZE               0x0D33\n#define GL_MAX_VIEWPORT_DIMS              0x0D3A\n#define GL_SUBPIXEL_BITS                  0x0D50\n#define GL_TEXTURE_1D                     0x0DE0\n#define GL_TEXTURE_2D                     0x0DE1\n#define GL_TEXTURE_WIDTH                  0x1000\n#define GL_TEXTURE_HEIGHT                 0x1001\n#define GL_TEXTURE_BORDER_COLOR           0x1004\n#define GL_DONT_CARE                      0x1100\n#define GL_FASTEST                        0x1101\n#define GL_NICEST                         0x1102\n#define GL_BYTE                           0x1400\n#define GL_UNSIGNED_BYTE                  0x1401\n#define GL_SHORT                          0x1402\n#define GL_UNSIGNED_SHORT                 0x1403\n#define GL_INT                            0x1404\n#define GL_UNSIGNED_INT                   0x1405\n#define GL_FLOAT                          0x1406\n#define GL_STACK_OVERFLOW                 0x0503\n#define GL_STACK_UNDERFLOW                0x0504\n#define GL_CLEAR                          0x1500\n#define GL_AND                            0x1501\n#define GL_AND_REVERSE                    0x1502\n#define GL_COPY                           0x1503\n#define GL_AND_INVERTED                   0x1504\n#define GL_NOOP                           0x1505\n#define GL_XOR                            0x1506\n#define GL_OR                             0x1507\n#define GL_NOR                            0x1508\n#define GL_EQUIV                          0x1509\n#define GL_INVERT                         0x150A\n#define GL_OR_REVERSE                     0x150B\n#define GL_COPY_INVERTED                  0x150C\n#define GL_OR_INVERTED                    0x150D\n#define GL_NAND                           0x150E\n#define GL_SET                            0x150F\n#define GL_TEXTURE                        0x1702\n#define GL_COLOR                          0x1800\n#define GL_DEPTH                          0x1801\n#define GL_STENCIL                        0x1802\n#define GL_STENCIL_INDEX                  0x1901\n#define GL_DEPTH_COMPONENT                0x1902\n#define GL_RED                            0x1903\n#define GL_GREEN                          0x1904\n#define GL_BLUE                           0x1905\n#define GL_ALPHA                          0x1906\n#define GL_RGB                            0x1907\n#define GL_RGBA                           0x1908\n#define GL_POINT                          0x1B00\n#define GL_LINE                           0x1B01\n#define GL_FILL                           0x1B02\n#define GL_KEEP                           0x1E00\n#define GL_REPLACE                        0x1E01\n#define GL_INCR                           0x1E02\n#define GL_DECR                           0x1E03\n#define GL_VENDOR                         0x1F00\n#define GL_RENDERER                       0x1F01\n#define GL_VERSION                        0x1F02\n#define GL_EXTENSIONS                     0x1F03\n#define GL_NEAREST                        0x2600\n#define GL_LINEAR                         0x2601\n#define GL_NEAREST_MIPMAP_NEAREST         0x2700\n#define GL_LINEAR_MIPMAP_NEAREST          0x2701\n#define GL_NEAREST_MIPMAP_LINEAR          0x2702\n#define GL_LINEAR_MIPMAP_LINEAR           0x2703\n#define GL_TEXTURE_MAG_FILTER             0x2800\n#define GL_TEXTURE_MIN_FILTER             0x2801\n#define GL_TEXTURE_WRAP_S                 0x2802\n#define GL_TEXTURE_WRAP_T                 0x2803\n#define GL_REPEAT                         0x2901\ntypedef void (APIENTRYP PFNGLCULLFACEPROC) (GLenum mode);\ntypedef void (APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode);\ntypedef void (APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode);\ntypedef void (APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width);\ntypedef void (APIENTRYP PFNGLPOINTSIZEPROC) (GLfloat size);\ntypedef void (APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);\ntypedef void (APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);\ntypedef void (APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);\ntypedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);\ntypedef void (APIENTRYP PFNGLTEXIMAGE1DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLDRAWBUFFERPROC) (GLenum buf);\ntypedef void (APIENTRYP PFNGLCLEARPROC) (GLbitfield mask);\ntypedef void (APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);\ntypedef void (APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s);\ntypedef void (APIENTRYP PFNGLCLEARDEPTHPROC) (GLdouble depth);\ntypedef void (APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask);\ntypedef void (APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);\ntypedef void (APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag);\ntypedef void (APIENTRYP PFNGLDISABLEPROC) (GLenum cap);\ntypedef void (APIENTRYP PFNGLENABLEPROC) (GLenum cap);\ntypedef void (APIENTRYP PFNGLFINISHPROC) (void);\ntypedef void (APIENTRYP PFNGLFLUSHPROC) (void);\ntypedef void (APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor);\ntypedef void (APIENTRYP PFNGLLOGICOPPROC) (GLenum opcode);\ntypedef void (APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask);\ntypedef void (APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass);\ntypedef void (APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func);\ntypedef void (APIENTRYP PFNGLPIXELSTOREFPROC) (GLenum pname, GLfloat param);\ntypedef void (APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLREADBUFFERPROC) (GLenum src);\ntypedef void (APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);\ntypedef void (APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *data);\ntypedef void (APIENTRYP PFNGLGETDOUBLEVPROC) (GLenum pname, GLdouble *data);\ntypedef GLenum (APIENTRYP PFNGLGETERRORPROC) (void);\ntypedef void (APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data);\ntypedef void (APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data);\ntypedef const GLubyte *(APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);\ntypedef void (APIENTRYP PFNGLGETTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, void *pixels);\ntypedef void (APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERFVPROC) (GLenum target, GLint level, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC) (GLenum target, GLint level, GLenum pname, GLint *params);\ntypedef GLboolean (APIENTRYP PFNGLISENABLEDPROC) (GLenum cap);\ntypedef void (APIENTRYP PFNGLDEPTHRANGEPROC) (GLdouble n, GLdouble f);\ntypedef void (APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glCullFace (GLenum mode);\nGLAPI void APIENTRY glFrontFace (GLenum mode);\nGLAPI void APIENTRY glHint (GLenum target, GLenum mode);\nGLAPI void APIENTRY glLineWidth (GLfloat width);\nGLAPI void APIENTRY glPointSize (GLfloat size);\nGLAPI void APIENTRY glPolygonMode (GLenum face, GLenum mode);\nGLAPI void APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);\nGLAPI void APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params);\nGLAPI void APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);\nGLAPI void APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params);\nGLAPI void APIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glDrawBuffer (GLenum buf);\nGLAPI void APIENTRY glClear (GLbitfield mask);\nGLAPI void APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);\nGLAPI void APIENTRY glClearStencil (GLint s);\nGLAPI void APIENTRY glClearDepth (GLdouble depth);\nGLAPI void APIENTRY glStencilMask (GLuint mask);\nGLAPI void APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);\nGLAPI void APIENTRY glDepthMask (GLboolean flag);\nGLAPI void APIENTRY glDisable (GLenum cap);\nGLAPI void APIENTRY glEnable (GLenum cap);\nGLAPI void APIENTRY glFinish (void);\nGLAPI void APIENTRY glFlush (void);\nGLAPI void APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);\nGLAPI void APIENTRY glLogicOp (GLenum opcode);\nGLAPI void APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);\nGLAPI void APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);\nGLAPI void APIENTRY glDepthFunc (GLenum func);\nGLAPI void APIENTRY glPixelStoref (GLenum pname, GLfloat param);\nGLAPI void APIENTRY glPixelStorei (GLenum pname, GLint param);\nGLAPI void APIENTRY glReadBuffer (GLenum src);\nGLAPI void APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);\nGLAPI void APIENTRY glGetBooleanv (GLenum pname, GLboolean *data);\nGLAPI void APIENTRY glGetDoublev (GLenum pname, GLdouble *data);\nGLAPI GLenum APIENTRY glGetError (void);\nGLAPI void APIENTRY glGetFloatv (GLenum pname, GLfloat *data);\nGLAPI void APIENTRY glGetIntegerv (GLenum pname, GLint *data);\nGLAPI const GLubyte *APIENTRY glGetString (GLenum name);\nGLAPI void APIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, void *pixels);\nGLAPI void APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params);\nGLAPI GLboolean APIENTRY glIsEnabled (GLenum cap);\nGLAPI void APIENTRY glDepthRange (GLdouble n, GLdouble f);\nGLAPI void APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);\n#endif\n#endif /* GL_VERSION_1_0 */\n\n#ifndef GL_VERSION_1_1\n#define GL_VERSION_1_1 1\ntypedef khronos_float_t GLclampf;\ntypedef double GLclampd;\n#define GL_COLOR_LOGIC_OP                 0x0BF2\n#define GL_POLYGON_OFFSET_UNITS           0x2A00\n#define GL_POLYGON_OFFSET_POINT           0x2A01\n#define GL_POLYGON_OFFSET_LINE            0x2A02\n#define GL_POLYGON_OFFSET_FILL            0x8037\n#define GL_POLYGON_OFFSET_FACTOR          0x8038\n#define GL_TEXTURE_BINDING_1D             0x8068\n#define GL_TEXTURE_BINDING_2D             0x8069\n#define GL_TEXTURE_INTERNAL_FORMAT        0x1003\n#define GL_TEXTURE_RED_SIZE               0x805C\n#define GL_TEXTURE_GREEN_SIZE             0x805D\n#define GL_TEXTURE_BLUE_SIZE              0x805E\n#define GL_TEXTURE_ALPHA_SIZE             0x805F\n#define GL_DOUBLE                         0x140A\n#define GL_PROXY_TEXTURE_1D               0x8063\n#define GL_PROXY_TEXTURE_2D               0x8064\n#define GL_R3_G3_B2                       0x2A10\n#define GL_RGB4                           0x804F\n#define GL_RGB5                           0x8050\n#define GL_RGB8                           0x8051\n#define GL_RGB10                          0x8052\n#define GL_RGB12                          0x8053\n#define GL_RGB16                          0x8054\n#define GL_RGBA2                          0x8055\n#define GL_RGBA4                          0x8056\n#define GL_RGB5_A1                        0x8057\n#define GL_RGBA8                          0x8058\n#define GL_RGB10_A2                       0x8059\n#define GL_RGBA12                         0x805A\n#define GL_RGBA16                         0x805B\n#define GL_VERTEX_ARRAY                   0x8074\ntypedef void (APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);\ntypedef void (APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);\ntypedef void (APIENTRYP PFNGLGETPOINTERVPROC) (GLenum pname, void **params);\ntypedef void (APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units);\ntypedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);\ntypedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);\ntypedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);\ntypedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);\ntypedef void (APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);\ntypedef void (APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);\ntypedef GLboolean (APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);\nGLAPI void APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);\nGLAPI void APIENTRY glGetPointerv (GLenum pname, void **params);\nGLAPI void APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);\nGLAPI void APIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);\nGLAPI void APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);\nGLAPI void APIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);\nGLAPI void APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glBindTexture (GLenum target, GLuint texture);\nGLAPI void APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);\nGLAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures);\nGLAPI GLboolean APIENTRY glIsTexture (GLuint texture);\n#endif\n#endif /* GL_VERSION_1_1 */\n\n#ifndef GL_VERSION_1_2\n#define GL_VERSION_1_2 1\n#define GL_UNSIGNED_BYTE_3_3_2            0x8032\n#define GL_UNSIGNED_SHORT_4_4_4_4         0x8033\n#define GL_UNSIGNED_SHORT_5_5_5_1         0x8034\n#define GL_UNSIGNED_INT_8_8_8_8           0x8035\n#define GL_UNSIGNED_INT_10_10_10_2        0x8036\n#define GL_TEXTURE_BINDING_3D             0x806A\n#define GL_PACK_SKIP_IMAGES               0x806B\n#define GL_PACK_IMAGE_HEIGHT              0x806C\n#define GL_UNPACK_SKIP_IMAGES             0x806D\n#define GL_UNPACK_IMAGE_HEIGHT            0x806E\n#define GL_TEXTURE_3D                     0x806F\n#define GL_PROXY_TEXTURE_3D               0x8070\n#define GL_TEXTURE_DEPTH                  0x8071\n#define GL_TEXTURE_WRAP_R                 0x8072\n#define GL_MAX_3D_TEXTURE_SIZE            0x8073\n#define GL_UNSIGNED_BYTE_2_3_3_REV        0x8362\n#define GL_UNSIGNED_SHORT_5_6_5           0x8363\n#define GL_UNSIGNED_SHORT_5_6_5_REV       0x8364\n#define GL_UNSIGNED_SHORT_4_4_4_4_REV     0x8365\n#define GL_UNSIGNED_SHORT_1_5_5_5_REV     0x8366\n#define GL_UNSIGNED_INT_8_8_8_8_REV       0x8367\n#define GL_UNSIGNED_INT_2_10_10_10_REV    0x8368\n#define GL_BGR                            0x80E0\n#define GL_BGRA                           0x80E1\n#define GL_MAX_ELEMENTS_VERTICES          0x80E8\n#define GL_MAX_ELEMENTS_INDICES           0x80E9\n#define GL_CLAMP_TO_EDGE                  0x812F\n#define GL_TEXTURE_MIN_LOD                0x813A\n#define GL_TEXTURE_MAX_LOD                0x813B\n#define GL_TEXTURE_BASE_LEVEL             0x813C\n#define GL_TEXTURE_MAX_LEVEL              0x813D\n#define GL_SMOOTH_POINT_SIZE_RANGE        0x0B12\n#define GL_SMOOTH_POINT_SIZE_GRANULARITY  0x0B13\n#define GL_SMOOTH_LINE_WIDTH_RANGE        0x0B22\n#define GL_SMOOTH_LINE_WIDTH_GRANULARITY  0x0B23\n#define GL_ALIASED_LINE_WIDTH_RANGE       0x846E\ntypedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);\ntypedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);\nGLAPI void APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);\n#endif\n#endif /* GL_VERSION_1_2 */\n\n#ifndef GL_VERSION_1_3\n#define GL_VERSION_1_3 1\n#define GL_TEXTURE0                       0x84C0\n#define GL_TEXTURE1                       0x84C1\n#define GL_TEXTURE2                       0x84C2\n#define GL_TEXTURE3                       0x84C3\n#define GL_TEXTURE4                       0x84C4\n#define GL_TEXTURE5                       0x84C5\n#define GL_TEXTURE6                       0x84C6\n#define GL_TEXTURE7                       0x84C7\n#define GL_TEXTURE8                       0x84C8\n#define GL_TEXTURE9                       0x84C9\n#define GL_TEXTURE10                      0x84CA\n#define GL_TEXTURE11                      0x84CB\n#define GL_TEXTURE12                      0x84CC\n#define GL_TEXTURE13                      0x84CD\n#define GL_TEXTURE14                      0x84CE\n#define GL_TEXTURE15                      0x84CF\n#define GL_TEXTURE16                      0x84D0\n#define GL_TEXTURE17                      0x84D1\n#define GL_TEXTURE18                      0x84D2\n#define GL_TEXTURE19                      0x84D3\n#define GL_TEXTURE20                      0x84D4\n#define GL_TEXTURE21                      0x84D5\n#define GL_TEXTURE22                      0x84D6\n#define GL_TEXTURE23                      0x84D7\n#define GL_TEXTURE24                      0x84D8\n#define GL_TEXTURE25                      0x84D9\n#define GL_TEXTURE26                      0x84DA\n#define GL_TEXTURE27                      0x84DB\n#define GL_TEXTURE28                      0x84DC\n#define GL_TEXTURE29                      0x84DD\n#define GL_TEXTURE30                      0x84DE\n#define GL_TEXTURE31                      0x84DF\n#define GL_ACTIVE_TEXTURE                 0x84E0\n#define GL_MULTISAMPLE                    0x809D\n#define GL_SAMPLE_ALPHA_TO_COVERAGE       0x809E\n#define GL_SAMPLE_ALPHA_TO_ONE            0x809F\n#define GL_SAMPLE_COVERAGE                0x80A0\n#define GL_SAMPLE_BUFFERS                 0x80A8\n#define GL_SAMPLES                        0x80A9\n#define GL_SAMPLE_COVERAGE_VALUE          0x80AA\n#define GL_SAMPLE_COVERAGE_INVERT         0x80AB\n#define GL_TEXTURE_CUBE_MAP               0x8513\n#define GL_TEXTURE_BINDING_CUBE_MAP       0x8514\n#define GL_TEXTURE_CUBE_MAP_POSITIVE_X    0x8515\n#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X    0x8516\n#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y    0x8517\n#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y    0x8518\n#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z    0x8519\n#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z    0x851A\n#define GL_PROXY_TEXTURE_CUBE_MAP         0x851B\n#define GL_MAX_CUBE_MAP_TEXTURE_SIZE      0x851C\n#define GL_COMPRESSED_RGB                 0x84ED\n#define GL_COMPRESSED_RGBA                0x84EE\n#define GL_TEXTURE_COMPRESSION_HINT       0x84EF\n#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE  0x86A0\n#define GL_TEXTURE_COMPRESSED             0x86A1\n#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2\n#define GL_COMPRESSED_TEXTURE_FORMATS     0x86A3\n#define GL_CLAMP_TO_BORDER                0x812D\ntypedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);\ntypedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, void *img);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glActiveTexture (GLenum texture);\nGLAPI void APIENTRY glSampleCoverage (GLfloat value, GLboolean invert);\nGLAPI void APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glGetCompressedTexImage (GLenum target, GLint level, void *img);\n#endif\n#endif /* GL_VERSION_1_3 */\n\n#ifndef GL_VERSION_1_4\n#define GL_VERSION_1_4 1\n#define GL_BLEND_DST_RGB                  0x80C8\n#define GL_BLEND_SRC_RGB                  0x80C9\n#define GL_BLEND_DST_ALPHA                0x80CA\n#define GL_BLEND_SRC_ALPHA                0x80CB\n#define GL_POINT_FADE_THRESHOLD_SIZE      0x8128\n#define GL_DEPTH_COMPONENT16              0x81A5\n#define GL_DEPTH_COMPONENT24              0x81A6\n#define GL_DEPTH_COMPONENT32              0x81A7\n#define GL_MIRRORED_REPEAT                0x8370\n#define GL_MAX_TEXTURE_LOD_BIAS           0x84FD\n#define GL_TEXTURE_LOD_BIAS               0x8501\n#define GL_INCR_WRAP                      0x8507\n#define GL_DECR_WRAP                      0x8508\n#define GL_TEXTURE_DEPTH_SIZE             0x884A\n#define GL_TEXTURE_COMPARE_MODE           0x884C\n#define GL_TEXTURE_COMPARE_FUNC           0x884D\n#define GL_BLEND_COLOR                    0x8005\n#define GL_BLEND_EQUATION                 0x8009\n#define GL_CONSTANT_COLOR                 0x8001\n#define GL_ONE_MINUS_CONSTANT_COLOR       0x8002\n#define GL_CONSTANT_ALPHA                 0x8003\n#define GL_ONE_MINUS_CONSTANT_ALPHA       0x8004\n#define GL_FUNC_ADD                       0x8006\n#define GL_FUNC_REVERSE_SUBTRACT          0x800B\n#define GL_FUNC_SUBTRACT                  0x800A\n#define GL_MIN                            0x8007\n#define GL_MAX                            0x8008\ntypedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);\ntypedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount);\ntypedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount);\ntypedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param);\ntypedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params);\ntypedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params);\ntypedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);\ntypedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);\nGLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount);\nGLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount);\nGLAPI void APIENTRY glPointParameterf (GLenum pname, GLfloat param);\nGLAPI void APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params);\nGLAPI void APIENTRY glPointParameteri (GLenum pname, GLint param);\nGLAPI void APIENTRY glPointParameteriv (GLenum pname, const GLint *params);\nGLAPI void APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);\nGLAPI void APIENTRY glBlendEquation (GLenum mode);\n#endif\n#endif /* GL_VERSION_1_4 */\n\n#ifndef GL_VERSION_1_5\n#define GL_VERSION_1_5 1\ntypedef khronos_ssize_t GLsizeiptr;\ntypedef khronos_intptr_t GLintptr;\n#define GL_BUFFER_SIZE                    0x8764\n#define GL_BUFFER_USAGE                   0x8765\n#define GL_QUERY_COUNTER_BITS             0x8864\n#define GL_CURRENT_QUERY                  0x8865\n#define GL_QUERY_RESULT                   0x8866\n#define GL_QUERY_RESULT_AVAILABLE         0x8867\n#define GL_ARRAY_BUFFER                   0x8892\n#define GL_ELEMENT_ARRAY_BUFFER           0x8893\n#define GL_ARRAY_BUFFER_BINDING           0x8894\n#define GL_ELEMENT_ARRAY_BUFFER_BINDING   0x8895\n#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F\n#define GL_READ_ONLY                      0x88B8\n#define GL_WRITE_ONLY                     0x88B9\n#define GL_READ_WRITE                     0x88BA\n#define GL_BUFFER_ACCESS                  0x88BB\n#define GL_BUFFER_MAPPED                  0x88BC\n#define GL_BUFFER_MAP_POINTER             0x88BD\n#define GL_STREAM_DRAW                    0x88E0\n#define GL_STREAM_READ                    0x88E1\n#define GL_STREAM_COPY                    0x88E2\n#define GL_STATIC_DRAW                    0x88E4\n#define GL_STATIC_READ                    0x88E5\n#define GL_STATIC_COPY                    0x88E6\n#define GL_DYNAMIC_DRAW                   0x88E8\n#define GL_DYNAMIC_READ                   0x88E9\n#define GL_DYNAMIC_COPY                   0x88EA\n#define GL_SAMPLES_PASSED                 0x8914\n#define GL_SRC1_ALPHA                     0x8589\ntypedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids);\ntypedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids);\ntypedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id);\ntypedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);\ntypedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target);\ntypedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params);\ntypedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);\ntypedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);\ntypedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);\ntypedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer);\ntypedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);\ntypedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);\ntypedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void *data);\ntypedef void *(APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);\ntypedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target);\ntypedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void **params);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glGenQueries (GLsizei n, GLuint *ids);\nGLAPI void APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids);\nGLAPI GLboolean APIENTRY glIsQuery (GLuint id);\nGLAPI void APIENTRY glBeginQuery (GLenum target, GLuint id);\nGLAPI void APIENTRY glEndQuery (GLenum target);\nGLAPI void APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetQueryObjectiv (GLuint id, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params);\nGLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer);\nGLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);\nGLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);\nGLAPI GLboolean APIENTRY glIsBuffer (GLuint buffer);\nGLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);\nGLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);\nGLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, void *data);\nGLAPI void *APIENTRY glMapBuffer (GLenum target, GLenum access);\nGLAPI GLboolean APIENTRY glUnmapBuffer (GLenum target);\nGLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params);\n#endif\n#endif /* GL_VERSION_1_5 */\n\n#ifndef GL_VERSION_2_0\n#define GL_VERSION_2_0 1\ntypedef char GLchar;\ntypedef khronos_int16_t GLshort;\ntypedef khronos_int8_t GLbyte;\ntypedef khronos_uint16_t GLushort;\n#define GL_BLEND_EQUATION_RGB             0x8009\n#define GL_VERTEX_ATTRIB_ARRAY_ENABLED    0x8622\n#define GL_VERTEX_ATTRIB_ARRAY_SIZE       0x8623\n#define GL_VERTEX_ATTRIB_ARRAY_STRIDE     0x8624\n#define GL_VERTEX_ATTRIB_ARRAY_TYPE       0x8625\n#define GL_CURRENT_VERTEX_ATTRIB          0x8626\n#define GL_VERTEX_PROGRAM_POINT_SIZE      0x8642\n#define GL_VERTEX_ATTRIB_ARRAY_POINTER    0x8645\n#define GL_STENCIL_BACK_FUNC              0x8800\n#define GL_STENCIL_BACK_FAIL              0x8801\n#define GL_STENCIL_BACK_PASS_DEPTH_FAIL   0x8802\n#define GL_STENCIL_BACK_PASS_DEPTH_PASS   0x8803\n#define GL_MAX_DRAW_BUFFERS               0x8824\n#define GL_DRAW_BUFFER0                   0x8825\n#define GL_DRAW_BUFFER1                   0x8826\n#define GL_DRAW_BUFFER2                   0x8827\n#define GL_DRAW_BUFFER3                   0x8828\n#define GL_DRAW_BUFFER4                   0x8829\n#define GL_DRAW_BUFFER5                   0x882A\n#define GL_DRAW_BUFFER6                   0x882B\n#define GL_DRAW_BUFFER7                   0x882C\n#define GL_DRAW_BUFFER8                   0x882D\n#define GL_DRAW_BUFFER9                   0x882E\n#define GL_DRAW_BUFFER10                  0x882F\n#define GL_DRAW_BUFFER11                  0x8830\n#define GL_DRAW_BUFFER12                  0x8831\n#define GL_DRAW_BUFFER13                  0x8832\n#define GL_DRAW_BUFFER14                  0x8833\n#define GL_DRAW_BUFFER15                  0x8834\n#define GL_BLEND_EQUATION_ALPHA           0x883D\n#define GL_MAX_VERTEX_ATTRIBS             0x8869\n#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A\n#define GL_MAX_TEXTURE_IMAGE_UNITS        0x8872\n#define GL_FRAGMENT_SHADER                0x8B30\n#define GL_VERTEX_SHADER                  0x8B31\n#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49\n#define GL_MAX_VERTEX_UNIFORM_COMPONENTS  0x8B4A\n#define GL_MAX_VARYING_FLOATS             0x8B4B\n#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C\n#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D\n#define GL_SHADER_TYPE                    0x8B4F\n#define GL_FLOAT_VEC2                     0x8B50\n#define GL_FLOAT_VEC3                     0x8B51\n#define GL_FLOAT_VEC4                     0x8B52\n#define GL_INT_VEC2                       0x8B53\n#define GL_INT_VEC3                       0x8B54\n#define GL_INT_VEC4                       0x8B55\n#define GL_BOOL                           0x8B56\n#define GL_BOOL_VEC2                      0x8B57\n#define GL_BOOL_VEC3                      0x8B58\n#define GL_BOOL_VEC4                      0x8B59\n#define GL_FLOAT_MAT2                     0x8B5A\n#define GL_FLOAT_MAT3                     0x8B5B\n#define GL_FLOAT_MAT4                     0x8B5C\n#define GL_SAMPLER_1D                     0x8B5D\n#define GL_SAMPLER_2D                     0x8B5E\n#define GL_SAMPLER_3D                     0x8B5F\n#define GL_SAMPLER_CUBE                   0x8B60\n#define GL_SAMPLER_1D_SHADOW              0x8B61\n#define GL_SAMPLER_2D_SHADOW              0x8B62\n#define GL_DELETE_STATUS                  0x8B80\n#define GL_COMPILE_STATUS                 0x8B81\n#define GL_LINK_STATUS                    0x8B82\n#define GL_VALIDATE_STATUS                0x8B83\n#define GL_INFO_LOG_LENGTH                0x8B84\n#define GL_ATTACHED_SHADERS               0x8B85\n#define GL_ACTIVE_UNIFORMS                0x8B86\n#define GL_ACTIVE_UNIFORM_MAX_LENGTH      0x8B87\n#define GL_SHADER_SOURCE_LENGTH           0x8B88\n#define GL_ACTIVE_ATTRIBUTES              0x8B89\n#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH    0x8B8A\n#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B\n#define GL_SHADING_LANGUAGE_VERSION       0x8B8C\n#define GL_CURRENT_PROGRAM                0x8B8D\n#define GL_POINT_SPRITE_COORD_ORIGIN      0x8CA0\n#define GL_LOWER_LEFT                     0x8CA1\n#define GL_UPPER_LEFT                     0x8CA2\n#define GL_STENCIL_BACK_REF               0x8CA3\n#define GL_STENCIL_BACK_VALUE_MASK        0x8CA4\n#define GL_STENCIL_BACK_WRITEMASK         0x8CA5\ntypedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);\ntypedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs);\ntypedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);\ntypedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask);\ntypedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask);\ntypedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);\ntypedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name);\ntypedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);\ntypedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void);\ntypedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);\ntypedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);\ntypedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);\ntypedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);\ntypedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);\ntypedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);\ntypedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);\ntypedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);\ntypedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);\ntypedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);\ntypedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);\ntypedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);\ntypedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);\ntypedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);\ntypedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer);\ntypedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);\ntypedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader);\ntypedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);\ntypedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);\ntypedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);\ntypedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);\ntypedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);\ntypedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);\ntypedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);\ntypedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);\ntypedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);\ntypedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);\ntypedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);\ntypedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);\nGLAPI void APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs);\nGLAPI void APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);\nGLAPI void APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);\nGLAPI void APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);\nGLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader);\nGLAPI void APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name);\nGLAPI void APIENTRY glCompileShader (GLuint shader);\nGLAPI GLuint APIENTRY glCreateProgram (void);\nGLAPI GLuint APIENTRY glCreateShader (GLenum type);\nGLAPI void APIENTRY glDeleteProgram (GLuint program);\nGLAPI void APIENTRY glDeleteShader (GLuint shader);\nGLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader);\nGLAPI void APIENTRY glDisableVertexAttribArray (GLuint index);\nGLAPI void APIENTRY glEnableVertexAttribArray (GLuint index);\nGLAPI void APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);\nGLAPI void APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);\nGLAPI void APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);\nGLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);\nGLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);\nGLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);\nGLAPI void APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);\nGLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);\nGLAPI void APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params);\nGLAPI void APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params);\nGLAPI void APIENTRY glGetVertexAttribdv (GLuint index, GLenum pname, GLdouble *params);\nGLAPI void APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer);\nGLAPI GLboolean APIENTRY glIsProgram (GLuint program);\nGLAPI GLboolean APIENTRY glIsShader (GLuint shader);\nGLAPI void APIENTRY glLinkProgram (GLuint program);\nGLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);\nGLAPI void APIENTRY glUseProgram (GLuint program);\nGLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0);\nGLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);\nGLAPI void APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);\nGLAPI void APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);\nGLAPI void APIENTRY glUniform1i (GLint location, GLint v0);\nGLAPI void APIENTRY glUniform2i (GLint location, GLint v0, GLint v1);\nGLAPI void APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2);\nGLAPI void APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);\nGLAPI void APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glValidateProgram (GLuint program);\nGLAPI void APIENTRY glVertexAttrib1d (GLuint index, GLdouble x);\nGLAPI void APIENTRY glVertexAttrib1dv (GLuint index, const GLdouble *v);\nGLAPI void APIENTRY glVertexAttrib1f (GLuint index, GLfloat x);\nGLAPI void APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v);\nGLAPI void APIENTRY glVertexAttrib1s (GLuint index, GLshort x);\nGLAPI void APIENTRY glVertexAttrib1sv (GLuint index, const GLshort *v);\nGLAPI void APIENTRY glVertexAttrib2d (GLuint index, GLdouble x, GLdouble y);\nGLAPI void APIENTRY glVertexAttrib2dv (GLuint index, const GLdouble *v);\nGLAPI void APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y);\nGLAPI void APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v);\nGLAPI void APIENTRY glVertexAttrib2s (GLuint index, GLshort x, GLshort y);\nGLAPI void APIENTRY glVertexAttrib2sv (GLuint index, const GLshort *v);\nGLAPI void APIENTRY glVertexAttrib3d (GLuint index, GLdouble x, GLdouble y, GLdouble z);\nGLAPI void APIENTRY glVertexAttrib3dv (GLuint index, const GLdouble *v);\nGLAPI void APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z);\nGLAPI void APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v);\nGLAPI void APIENTRY glVertexAttrib3s (GLuint index, GLshort x, GLshort y, GLshort z);\nGLAPI void APIENTRY glVertexAttrib3sv (GLuint index, const GLshort *v);\nGLAPI void APIENTRY glVertexAttrib4Nbv (GLuint index, const GLbyte *v);\nGLAPI void APIENTRY glVertexAttrib4Niv (GLuint index, const GLint *v);\nGLAPI void APIENTRY glVertexAttrib4Nsv (GLuint index, const GLshort *v);\nGLAPI void APIENTRY glVertexAttrib4Nub (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);\nGLAPI void APIENTRY glVertexAttrib4Nubv (GLuint index, const GLubyte *v);\nGLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint index, const GLuint *v);\nGLAPI void APIENTRY glVertexAttrib4Nusv (GLuint index, const GLushort *v);\nGLAPI void APIENTRY glVertexAttrib4bv (GLuint index, const GLbyte *v);\nGLAPI void APIENTRY glVertexAttrib4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);\nGLAPI void APIENTRY glVertexAttrib4dv (GLuint index, const GLdouble *v);\nGLAPI void APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);\nGLAPI void APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v);\nGLAPI void APIENTRY glVertexAttrib4iv (GLuint index, const GLint *v);\nGLAPI void APIENTRY glVertexAttrib4s (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);\nGLAPI void APIENTRY glVertexAttrib4sv (GLuint index, const GLshort *v);\nGLAPI void APIENTRY glVertexAttrib4ubv (GLuint index, const GLubyte *v);\nGLAPI void APIENTRY glVertexAttrib4uiv (GLuint index, const GLuint *v);\nGLAPI void APIENTRY glVertexAttrib4usv (GLuint index, const GLushort *v);\nGLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);\n#endif\n#endif /* GL_VERSION_2_0 */\n\n#ifndef GL_VERSION_2_1\n#define GL_VERSION_2_1 1\n#define GL_PIXEL_PACK_BUFFER              0x88EB\n#define GL_PIXEL_UNPACK_BUFFER            0x88EC\n#define GL_PIXEL_PACK_BUFFER_BINDING      0x88ED\n#define GL_PIXEL_UNPACK_BUFFER_BINDING    0x88EF\n#define GL_FLOAT_MAT2x3                   0x8B65\n#define GL_FLOAT_MAT2x4                   0x8B66\n#define GL_FLOAT_MAT3x2                   0x8B67\n#define GL_FLOAT_MAT3x4                   0x8B68\n#define GL_FLOAT_MAT4x2                   0x8B69\n#define GL_FLOAT_MAT4x3                   0x8B6A\n#define GL_SRGB                           0x8C40\n#define GL_SRGB8                          0x8C41\n#define GL_SRGB_ALPHA                     0x8C42\n#define GL_SRGB8_ALPHA8                   0x8C43\n#define GL_COMPRESSED_SRGB                0x8C48\n#define GL_COMPRESSED_SRGB_ALPHA          0x8C49\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\n#endif\n#endif /* GL_VERSION_2_1 */\n\n#ifndef GL_VERSION_3_0\n#define GL_VERSION_3_0 1\ntypedef khronos_uint16_t GLhalf;\n#define GL_COMPARE_REF_TO_TEXTURE         0x884E\n#define GL_CLIP_DISTANCE0                 0x3000\n#define GL_CLIP_DISTANCE1                 0x3001\n#define GL_CLIP_DISTANCE2                 0x3002\n#define GL_CLIP_DISTANCE3                 0x3003\n#define GL_CLIP_DISTANCE4                 0x3004\n#define GL_CLIP_DISTANCE5                 0x3005\n#define GL_CLIP_DISTANCE6                 0x3006\n#define GL_CLIP_DISTANCE7                 0x3007\n#define GL_MAX_CLIP_DISTANCES             0x0D32\n#define GL_MAJOR_VERSION                  0x821B\n#define GL_MINOR_VERSION                  0x821C\n#define GL_NUM_EXTENSIONS                 0x821D\n#define GL_CONTEXT_FLAGS                  0x821E\n#define GL_COMPRESSED_RED                 0x8225\n#define GL_COMPRESSED_RG                  0x8226\n#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001\n#define GL_RGBA32F                        0x8814\n#define GL_RGB32F                         0x8815\n#define GL_RGBA16F                        0x881A\n#define GL_RGB16F                         0x881B\n#define GL_VERTEX_ATTRIB_ARRAY_INTEGER    0x88FD\n#define GL_MAX_ARRAY_TEXTURE_LAYERS       0x88FF\n#define GL_MIN_PROGRAM_TEXEL_OFFSET       0x8904\n#define GL_MAX_PROGRAM_TEXEL_OFFSET       0x8905\n#define GL_CLAMP_READ_COLOR               0x891C\n#define GL_FIXED_ONLY                     0x891D\n#define GL_MAX_VARYING_COMPONENTS         0x8B4B\n#define GL_TEXTURE_1D_ARRAY               0x8C18\n#define GL_PROXY_TEXTURE_1D_ARRAY         0x8C19\n#define GL_TEXTURE_2D_ARRAY               0x8C1A\n#define GL_PROXY_TEXTURE_2D_ARRAY         0x8C1B\n#define GL_TEXTURE_BINDING_1D_ARRAY       0x8C1C\n#define GL_TEXTURE_BINDING_2D_ARRAY       0x8C1D\n#define GL_R11F_G11F_B10F                 0x8C3A\n#define GL_UNSIGNED_INT_10F_11F_11F_REV   0x8C3B\n#define GL_RGB9_E5                        0x8C3D\n#define GL_UNSIGNED_INT_5_9_9_9_REV       0x8C3E\n#define GL_TEXTURE_SHARED_SIZE            0x8C3F\n#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76\n#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F\n#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80\n#define GL_TRANSFORM_FEEDBACK_VARYINGS    0x8C83\n#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84\n#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85\n#define GL_PRIMITIVES_GENERATED           0x8C87\n#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88\n#define GL_RASTERIZER_DISCARD             0x8C89\n#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A\n#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B\n#define GL_INTERLEAVED_ATTRIBS            0x8C8C\n#define GL_SEPARATE_ATTRIBS               0x8C8D\n#define GL_TRANSFORM_FEEDBACK_BUFFER      0x8C8E\n#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F\n#define GL_RGBA32UI                       0x8D70\n#define GL_RGB32UI                        0x8D71\n#define GL_RGBA16UI                       0x8D76\n#define GL_RGB16UI                        0x8D77\n#define GL_RGBA8UI                        0x8D7C\n#define GL_RGB8UI                         0x8D7D\n#define GL_RGBA32I                        0x8D82\n#define GL_RGB32I                         0x8D83\n#define GL_RGBA16I                        0x8D88\n#define GL_RGB16I                         0x8D89\n#define GL_RGBA8I                         0x8D8E\n#define GL_RGB8I                          0x8D8F\n#define GL_RED_INTEGER                    0x8D94\n#define GL_GREEN_INTEGER                  0x8D95\n#define GL_BLUE_INTEGER                   0x8D96\n#define GL_RGB_INTEGER                    0x8D98\n#define GL_RGBA_INTEGER                   0x8D99\n#define GL_BGR_INTEGER                    0x8D9A\n#define GL_BGRA_INTEGER                   0x8D9B\n#define GL_SAMPLER_1D_ARRAY               0x8DC0\n#define GL_SAMPLER_2D_ARRAY               0x8DC1\n#define GL_SAMPLER_1D_ARRAY_SHADOW        0x8DC3\n#define GL_SAMPLER_2D_ARRAY_SHADOW        0x8DC4\n#define GL_SAMPLER_CUBE_SHADOW            0x8DC5\n#define GL_UNSIGNED_INT_VEC2              0x8DC6\n#define GL_UNSIGNED_INT_VEC3              0x8DC7\n#define GL_UNSIGNED_INT_VEC4              0x8DC8\n#define GL_INT_SAMPLER_1D                 0x8DC9\n#define GL_INT_SAMPLER_2D                 0x8DCA\n#define GL_INT_SAMPLER_3D                 0x8DCB\n#define GL_INT_SAMPLER_CUBE               0x8DCC\n#define GL_INT_SAMPLER_1D_ARRAY           0x8DCE\n#define GL_INT_SAMPLER_2D_ARRAY           0x8DCF\n#define GL_UNSIGNED_INT_SAMPLER_1D        0x8DD1\n#define GL_UNSIGNED_INT_SAMPLER_2D        0x8DD2\n#define GL_UNSIGNED_INT_SAMPLER_3D        0x8DD3\n#define GL_UNSIGNED_INT_SAMPLER_CUBE      0x8DD4\n#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY  0x8DD6\n#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY  0x8DD7\n#define GL_QUERY_WAIT                     0x8E13\n#define GL_QUERY_NO_WAIT                  0x8E14\n#define GL_QUERY_BY_REGION_WAIT           0x8E15\n#define GL_QUERY_BY_REGION_NO_WAIT        0x8E16\n#define GL_BUFFER_ACCESS_FLAGS            0x911F\n#define GL_BUFFER_MAP_LENGTH              0x9120\n#define GL_BUFFER_MAP_OFFSET              0x9121\n#define GL_DEPTH_COMPONENT32F             0x8CAC\n#define GL_DEPTH32F_STENCIL8              0x8CAD\n#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD\n#define GL_INVALID_FRAMEBUFFER_OPERATION  0x0506\n#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210\n#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211\n#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212\n#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213\n#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214\n#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215\n#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216\n#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217\n#define GL_FRAMEBUFFER_DEFAULT            0x8218\n#define GL_FRAMEBUFFER_UNDEFINED          0x8219\n#define GL_DEPTH_STENCIL_ATTACHMENT       0x821A\n#define GL_MAX_RENDERBUFFER_SIZE          0x84E8\n#define GL_DEPTH_STENCIL                  0x84F9\n#define GL_UNSIGNED_INT_24_8              0x84FA\n#define GL_DEPTH24_STENCIL8               0x88F0\n#define GL_TEXTURE_STENCIL_SIZE           0x88F1\n#define GL_TEXTURE_RED_TYPE               0x8C10\n#define GL_TEXTURE_GREEN_TYPE             0x8C11\n#define GL_TEXTURE_BLUE_TYPE              0x8C12\n#define GL_TEXTURE_ALPHA_TYPE             0x8C13\n#define GL_TEXTURE_DEPTH_TYPE             0x8C16\n#define GL_UNSIGNED_NORMALIZED            0x8C17\n#define GL_FRAMEBUFFER_BINDING            0x8CA6\n#define GL_DRAW_FRAMEBUFFER_BINDING       0x8CA6\n#define GL_RENDERBUFFER_BINDING           0x8CA7\n#define GL_READ_FRAMEBUFFER               0x8CA8\n#define GL_DRAW_FRAMEBUFFER               0x8CA9\n#define GL_READ_FRAMEBUFFER_BINDING       0x8CAA\n#define GL_RENDERBUFFER_SAMPLES           0x8CAB\n#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0\n#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1\n#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2\n#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3\n#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4\n#define GL_FRAMEBUFFER_COMPLETE           0x8CD5\n#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6\n#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7\n#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB\n#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC\n#define GL_FRAMEBUFFER_UNSUPPORTED        0x8CDD\n#define GL_MAX_COLOR_ATTACHMENTS          0x8CDF\n#define GL_COLOR_ATTACHMENT0              0x8CE0\n#define GL_COLOR_ATTACHMENT1              0x8CE1\n#define GL_COLOR_ATTACHMENT2              0x8CE2\n#define GL_COLOR_ATTACHMENT3              0x8CE3\n#define GL_COLOR_ATTACHMENT4              0x8CE4\n#define GL_COLOR_ATTACHMENT5              0x8CE5\n#define GL_COLOR_ATTACHMENT6              0x8CE6\n#define GL_COLOR_ATTACHMENT7              0x8CE7\n#define GL_COLOR_ATTACHMENT8              0x8CE8\n#define GL_COLOR_ATTACHMENT9              0x8CE9\n#define GL_COLOR_ATTACHMENT10             0x8CEA\n#define GL_COLOR_ATTACHMENT11             0x8CEB\n#define GL_COLOR_ATTACHMENT12             0x8CEC\n#define GL_COLOR_ATTACHMENT13             0x8CED\n#define GL_COLOR_ATTACHMENT14             0x8CEE\n#define GL_COLOR_ATTACHMENT15             0x8CEF\n#define GL_COLOR_ATTACHMENT16             0x8CF0\n#define GL_COLOR_ATTACHMENT17             0x8CF1\n#define GL_COLOR_ATTACHMENT18             0x8CF2\n#define GL_COLOR_ATTACHMENT19             0x8CF3\n#define GL_COLOR_ATTACHMENT20             0x8CF4\n#define GL_COLOR_ATTACHMENT21             0x8CF5\n#define GL_COLOR_ATTACHMENT22             0x8CF6\n#define GL_COLOR_ATTACHMENT23             0x8CF7\n#define GL_COLOR_ATTACHMENT24             0x8CF8\n#define GL_COLOR_ATTACHMENT25             0x8CF9\n#define GL_COLOR_ATTACHMENT26             0x8CFA\n#define GL_COLOR_ATTACHMENT27             0x8CFB\n#define GL_COLOR_ATTACHMENT28             0x8CFC\n#define GL_COLOR_ATTACHMENT29             0x8CFD\n#define GL_COLOR_ATTACHMENT30             0x8CFE\n#define GL_COLOR_ATTACHMENT31             0x8CFF\n#define GL_DEPTH_ATTACHMENT               0x8D00\n#define GL_STENCIL_ATTACHMENT             0x8D20\n#define GL_FRAMEBUFFER                    0x8D40\n#define GL_RENDERBUFFER                   0x8D41\n#define GL_RENDERBUFFER_WIDTH             0x8D42\n#define GL_RENDERBUFFER_HEIGHT            0x8D43\n#define GL_RENDERBUFFER_INTERNAL_FORMAT   0x8D44\n#define GL_STENCIL_INDEX1                 0x8D46\n#define GL_STENCIL_INDEX4                 0x8D47\n#define GL_STENCIL_INDEX8                 0x8D48\n#define GL_STENCIL_INDEX16                0x8D49\n#define GL_RENDERBUFFER_RED_SIZE          0x8D50\n#define GL_RENDERBUFFER_GREEN_SIZE        0x8D51\n#define GL_RENDERBUFFER_BLUE_SIZE         0x8D52\n#define GL_RENDERBUFFER_ALPHA_SIZE        0x8D53\n#define GL_RENDERBUFFER_DEPTH_SIZE        0x8D54\n#define GL_RENDERBUFFER_STENCIL_SIZE      0x8D55\n#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56\n#define GL_MAX_SAMPLES                    0x8D57\n#define GL_FRAMEBUFFER_SRGB               0x8DB9\n#define GL_HALF_FLOAT                     0x140B\n#define GL_MAP_READ_BIT                   0x0001\n#define GL_MAP_WRITE_BIT                  0x0002\n#define GL_MAP_INVALIDATE_RANGE_BIT       0x0004\n#define GL_MAP_INVALIDATE_BUFFER_BIT      0x0008\n#define GL_MAP_FLUSH_EXPLICIT_BIT         0x0010\n#define GL_MAP_UNSYNCHRONIZED_BIT         0x0020\n#define GL_COMPRESSED_RED_RGTC1           0x8DBB\n#define GL_COMPRESSED_SIGNED_RED_RGTC1    0x8DBC\n#define GL_COMPRESSED_RG_RGTC2            0x8DBD\n#define GL_COMPRESSED_SIGNED_RG_RGTC2     0x8DBE\n#define GL_RG                             0x8227\n#define GL_RG_INTEGER                     0x8228\n#define GL_R8                             0x8229\n#define GL_R16                            0x822A\n#define GL_RG8                            0x822B\n#define GL_RG16                           0x822C\n#define GL_R16F                           0x822D\n#define GL_R32F                           0x822E\n#define GL_RG16F                          0x822F\n#define GL_RG32F                          0x8230\n#define GL_R8I                            0x8231\n#define GL_R8UI                           0x8232\n#define GL_R16I                           0x8233\n#define GL_R16UI                          0x8234\n#define GL_R32I                           0x8235\n#define GL_R32UI                          0x8236\n#define GL_RG8I                           0x8237\n#define GL_RG8UI                          0x8238\n#define GL_RG16I                          0x8239\n#define GL_RG16UI                         0x823A\n#define GL_RG32I                          0x823B\n#define GL_RG32UI                         0x823C\n#define GL_VERTEX_ARRAY_BINDING           0x85B5\ntypedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);\ntypedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data);\ntypedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data);\ntypedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index);\ntypedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index);\ntypedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index);\ntypedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode);\ntypedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void);\ntypedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);\ntypedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer);\ntypedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode);\ntypedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);\ntypedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp);\ntypedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode);\ntypedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v);\ntypedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params);\ntypedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name);\ntypedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name);\ntypedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0);\ntypedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1);\ntypedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);\ntypedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);\ntypedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params);\ntypedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params);\ntypedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params);\ntypedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value);\ntypedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value);\ntypedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);\ntypedef const GLubyte *(APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);\ntypedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer);\ntypedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer);\ntypedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers);\ntypedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers);\ntypedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);\ntypedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer);\ntypedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);\ntypedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers);\ntypedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers);\ntypedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);\ntypedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target);\ntypedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);\ntypedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);\ntypedef void *(APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);\ntypedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length);\ntypedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);\ntypedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);\ntypedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);\ntypedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);\nGLAPI void APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data);\nGLAPI void APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data);\nGLAPI void APIENTRY glEnablei (GLenum target, GLuint index);\nGLAPI void APIENTRY glDisablei (GLenum target, GLuint index);\nGLAPI GLboolean APIENTRY glIsEnabledi (GLenum target, GLuint index);\nGLAPI void APIENTRY glBeginTransformFeedback (GLenum primitiveMode);\nGLAPI void APIENTRY glEndTransformFeedback (void);\nGLAPI void APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);\nGLAPI void APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer);\nGLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode);\nGLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);\nGLAPI void APIENTRY glClampColor (GLenum target, GLenum clamp);\nGLAPI void APIENTRY glBeginConditionalRender (GLuint id, GLenum mode);\nGLAPI void APIENTRY glEndConditionalRender (void);\nGLAPI void APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);\nGLAPI void APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params);\nGLAPI void APIENTRY glVertexAttribI1i (GLuint index, GLint x);\nGLAPI void APIENTRY glVertexAttribI2i (GLuint index, GLint x, GLint y);\nGLAPI void APIENTRY glVertexAttribI3i (GLuint index, GLint x, GLint y, GLint z);\nGLAPI void APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w);\nGLAPI void APIENTRY glVertexAttribI1ui (GLuint index, GLuint x);\nGLAPI void APIENTRY glVertexAttribI2ui (GLuint index, GLuint x, GLuint y);\nGLAPI void APIENTRY glVertexAttribI3ui (GLuint index, GLuint x, GLuint y, GLuint z);\nGLAPI void APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);\nGLAPI void APIENTRY glVertexAttribI1iv (GLuint index, const GLint *v);\nGLAPI void APIENTRY glVertexAttribI2iv (GLuint index, const GLint *v);\nGLAPI void APIENTRY glVertexAttribI3iv (GLuint index, const GLint *v);\nGLAPI void APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v);\nGLAPI void APIENTRY glVertexAttribI1uiv (GLuint index, const GLuint *v);\nGLAPI void APIENTRY glVertexAttribI2uiv (GLuint index, const GLuint *v);\nGLAPI void APIENTRY glVertexAttribI3uiv (GLuint index, const GLuint *v);\nGLAPI void APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v);\nGLAPI void APIENTRY glVertexAttribI4bv (GLuint index, const GLbyte *v);\nGLAPI void APIENTRY glVertexAttribI4sv (GLuint index, const GLshort *v);\nGLAPI void APIENTRY glVertexAttribI4ubv (GLuint index, const GLubyte *v);\nGLAPI void APIENTRY glVertexAttribI4usv (GLuint index, const GLushort *v);\nGLAPI void APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params);\nGLAPI void APIENTRY glBindFragDataLocation (GLuint program, GLuint color, const GLchar *name);\nGLAPI GLint APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name);\nGLAPI void APIENTRY glUniform1ui (GLint location, GLuint v0);\nGLAPI void APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1);\nGLAPI void APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2);\nGLAPI void APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);\nGLAPI void APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params);\nGLAPI void APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params);\nGLAPI void APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params);\nGLAPI void APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value);\nGLAPI void APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value);\nGLAPI void APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value);\nGLAPI void APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);\nGLAPI const GLubyte *APIENTRY glGetStringi (GLenum name, GLuint index);\nGLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint renderbuffer);\nGLAPI void APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);\nGLAPI void APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers);\nGLAPI void APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers);\nGLAPI void APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params);\nGLAPI GLboolean APIENTRY glIsFramebuffer (GLuint framebuffer);\nGLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);\nGLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers);\nGLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);\nGLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum target);\nGLAPI void APIENTRY glFramebufferTexture1D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);\nGLAPI void APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);\nGLAPI void APIENTRY glFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);\nGLAPI void APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);\nGLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGenerateMipmap (GLenum target);\nGLAPI void APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);\nGLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);\nGLAPI void *APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);\nGLAPI void APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length);\nGLAPI void APIENTRY glBindVertexArray (GLuint array);\nGLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays);\nGLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays);\nGLAPI GLboolean APIENTRY glIsVertexArray (GLuint array);\n#endif\n#endif /* GL_VERSION_3_0 */\n\n#ifndef GL_VERSION_3_1\n#define GL_VERSION_3_1 1\n#define GL_SAMPLER_2D_RECT                0x8B63\n#define GL_SAMPLER_2D_RECT_SHADOW         0x8B64\n#define GL_SAMPLER_BUFFER                 0x8DC2\n#define GL_INT_SAMPLER_2D_RECT            0x8DCD\n#define GL_INT_SAMPLER_BUFFER             0x8DD0\n#define GL_UNSIGNED_INT_SAMPLER_2D_RECT   0x8DD5\n#define GL_UNSIGNED_INT_SAMPLER_BUFFER    0x8DD8\n#define GL_TEXTURE_BUFFER                 0x8C2A\n#define GL_MAX_TEXTURE_BUFFER_SIZE        0x8C2B\n#define GL_TEXTURE_BINDING_BUFFER         0x8C2C\n#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D\n#define GL_TEXTURE_RECTANGLE              0x84F5\n#define GL_TEXTURE_BINDING_RECTANGLE      0x84F6\n#define GL_PROXY_TEXTURE_RECTANGLE        0x84F7\n#define GL_MAX_RECTANGLE_TEXTURE_SIZE     0x84F8\n#define GL_R8_SNORM                       0x8F94\n#define GL_RG8_SNORM                      0x8F95\n#define GL_RGB8_SNORM                     0x8F96\n#define GL_RGBA8_SNORM                    0x8F97\n#define GL_R16_SNORM                      0x8F98\n#define GL_RG16_SNORM                     0x8F99\n#define GL_RGB16_SNORM                    0x8F9A\n#define GL_RGBA16_SNORM                   0x8F9B\n#define GL_SIGNED_NORMALIZED              0x8F9C\n#define GL_PRIMITIVE_RESTART              0x8F9D\n#define GL_PRIMITIVE_RESTART_INDEX        0x8F9E\n#define GL_COPY_READ_BUFFER               0x8F36\n#define GL_COPY_WRITE_BUFFER              0x8F37\n#define GL_UNIFORM_BUFFER                 0x8A11\n#define GL_UNIFORM_BUFFER_BINDING         0x8A28\n#define GL_UNIFORM_BUFFER_START           0x8A29\n#define GL_UNIFORM_BUFFER_SIZE            0x8A2A\n#define GL_MAX_VERTEX_UNIFORM_BLOCKS      0x8A2B\n#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS    0x8A2C\n#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS    0x8A2D\n#define GL_MAX_COMBINED_UNIFORM_BLOCKS    0x8A2E\n#define GL_MAX_UNIFORM_BUFFER_BINDINGS    0x8A2F\n#define GL_MAX_UNIFORM_BLOCK_SIZE         0x8A30\n#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31\n#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32\n#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33\n#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34\n#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35\n#define GL_ACTIVE_UNIFORM_BLOCKS          0x8A36\n#define GL_UNIFORM_TYPE                   0x8A37\n#define GL_UNIFORM_SIZE                   0x8A38\n#define GL_UNIFORM_NAME_LENGTH            0x8A39\n#define GL_UNIFORM_BLOCK_INDEX            0x8A3A\n#define GL_UNIFORM_OFFSET                 0x8A3B\n#define GL_UNIFORM_ARRAY_STRIDE           0x8A3C\n#define GL_UNIFORM_MATRIX_STRIDE          0x8A3D\n#define GL_UNIFORM_IS_ROW_MAJOR           0x8A3E\n#define GL_UNIFORM_BLOCK_BINDING          0x8A3F\n#define GL_UNIFORM_BLOCK_DATA_SIZE        0x8A40\n#define GL_UNIFORM_BLOCK_NAME_LENGTH      0x8A41\n#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS  0x8A42\n#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43\n#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44\n#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45\n#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46\n#define GL_INVALID_INDEX                  0xFFFFFFFFu\ntypedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount);\ntypedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount);\ntypedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer);\ntypedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index);\ntypedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);\ntypedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices);\ntypedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName);\ntypedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName);\ntypedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);\ntypedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount);\nGLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount);\nGLAPI void APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer);\nGLAPI void APIENTRY glPrimitiveRestartIndex (GLuint index);\nGLAPI void APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);\nGLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices);\nGLAPI void APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetActiveUniformName (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName);\nGLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName);\nGLAPI void APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);\nGLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);\n#endif\n#endif /* GL_VERSION_3_1 */\n\n#ifndef GL_VERSION_3_2\n#define GL_VERSION_3_2 1\ntypedef struct __GLsync *GLsync;\ntypedef khronos_uint64_t GLuint64;\ntypedef khronos_int64_t GLint64;\n#define GL_CONTEXT_CORE_PROFILE_BIT       0x00000001\n#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002\n#define GL_LINES_ADJACENCY                0x000A\n#define GL_LINE_STRIP_ADJACENCY           0x000B\n#define GL_TRIANGLES_ADJACENCY            0x000C\n#define GL_TRIANGLE_STRIP_ADJACENCY       0x000D\n#define GL_PROGRAM_POINT_SIZE             0x8642\n#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29\n#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7\n#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8\n#define GL_GEOMETRY_SHADER                0x8DD9\n#define GL_GEOMETRY_VERTICES_OUT          0x8916\n#define GL_GEOMETRY_INPUT_TYPE            0x8917\n#define GL_GEOMETRY_OUTPUT_TYPE           0x8918\n#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF\n#define GL_MAX_GEOMETRY_OUTPUT_VERTICES   0x8DE0\n#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1\n#define GL_MAX_VERTEX_OUTPUT_COMPONENTS   0x9122\n#define GL_MAX_GEOMETRY_INPUT_COMPONENTS  0x9123\n#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124\n#define GL_MAX_FRAGMENT_INPUT_COMPONENTS  0x9125\n#define GL_CONTEXT_PROFILE_MASK           0x9126\n#define GL_DEPTH_CLAMP                    0x864F\n#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C\n#define GL_FIRST_VERTEX_CONVENTION        0x8E4D\n#define GL_LAST_VERTEX_CONVENTION         0x8E4E\n#define GL_PROVOKING_VERTEX               0x8E4F\n#define GL_TEXTURE_CUBE_MAP_SEAMLESS      0x884F\n#define GL_MAX_SERVER_WAIT_TIMEOUT        0x9111\n#define GL_OBJECT_TYPE                    0x9112\n#define GL_SYNC_CONDITION                 0x9113\n#define GL_SYNC_STATUS                    0x9114\n#define GL_SYNC_FLAGS                     0x9115\n#define GL_SYNC_FENCE                     0x9116\n#define GL_SYNC_GPU_COMMANDS_COMPLETE     0x9117\n#define GL_UNSIGNALED                     0x9118\n#define GL_SIGNALED                       0x9119\n#define GL_ALREADY_SIGNALED               0x911A\n#define GL_TIMEOUT_EXPIRED                0x911B\n#define GL_CONDITION_SATISFIED            0x911C\n#define GL_WAIT_FAILED                    0x911D\n#define GL_TIMEOUT_IGNORED                0xFFFFFFFFFFFFFFFFull\n#define GL_SYNC_FLUSH_COMMANDS_BIT        0x00000001\n#define GL_SAMPLE_POSITION                0x8E50\n#define GL_SAMPLE_MASK                    0x8E51\n#define GL_SAMPLE_MASK_VALUE              0x8E52\n#define GL_MAX_SAMPLE_MASK_WORDS          0x8E59\n#define GL_TEXTURE_2D_MULTISAMPLE         0x9100\n#define GL_PROXY_TEXTURE_2D_MULTISAMPLE   0x9101\n#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY   0x9102\n#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103\n#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104\n#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105\n#define GL_TEXTURE_SAMPLES                0x9106\n#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107\n#define GL_SAMPLER_2D_MULTISAMPLE         0x9108\n#define GL_INT_SAMPLER_2D_MULTISAMPLE     0x9109\n#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A\n#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY   0x910B\n#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C\n#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D\n#define GL_MAX_COLOR_TEXTURE_SAMPLES      0x910E\n#define GL_MAX_DEPTH_TEXTURE_SAMPLES      0x910F\n#define GL_MAX_INTEGER_SAMPLES            0x9110\ntypedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);\ntypedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);\ntypedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);\ntypedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex);\ntypedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode);\ntypedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags);\ntypedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync);\ntypedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync);\ntypedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);\ntypedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);\ntypedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data);\ntypedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values);\ntypedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);\ntypedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);\ntypedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);\ntypedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);\ntypedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val);\ntypedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint maskNumber, GLbitfield mask);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);\nGLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);\nGLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);\nGLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex);\nGLAPI void APIENTRY glProvokingVertex (GLenum mode);\nGLAPI GLsync APIENTRY glFenceSync (GLenum condition, GLbitfield flags);\nGLAPI GLboolean APIENTRY glIsSync (GLsync sync);\nGLAPI void APIENTRY glDeleteSync (GLsync sync);\nGLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);\nGLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);\nGLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *data);\nGLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values);\nGLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data);\nGLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params);\nGLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level);\nGLAPI void APIENTRY glTexImage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);\nGLAPI void APIENTRY glTexImage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);\nGLAPI void APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val);\nGLAPI void APIENTRY glSampleMaski (GLuint maskNumber, GLbitfield mask);\n#endif\n#endif /* GL_VERSION_3_2 */\n\n#ifndef GL_VERSION_3_3\n#define GL_VERSION_3_3 1\n#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR    0x88FE\n#define GL_SRC1_COLOR                     0x88F9\n#define GL_ONE_MINUS_SRC1_COLOR           0x88FA\n#define GL_ONE_MINUS_SRC1_ALPHA           0x88FB\n#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS   0x88FC\n#define GL_ANY_SAMPLES_PASSED             0x8C2F\n#define GL_SAMPLER_BINDING                0x8919\n#define GL_RGB10_A2UI                     0x906F\n#define GL_TEXTURE_SWIZZLE_R              0x8E42\n#define GL_TEXTURE_SWIZZLE_G              0x8E43\n#define GL_TEXTURE_SWIZZLE_B              0x8E44\n#define GL_TEXTURE_SWIZZLE_A              0x8E45\n#define GL_TEXTURE_SWIZZLE_RGBA           0x8E46\n#define GL_TIME_ELAPSED                   0x88BF\n#define GL_TIMESTAMP                      0x8E28\n#define GL_INT_2_10_10_10_REV             0x8D9F\ntypedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);\ntypedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar *name);\ntypedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers);\ntypedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers);\ntypedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler);\ntypedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);\ntypedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param);\ntypedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param);\ntypedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param);\ntypedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param);\ntypedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param);\ntypedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params);\ntypedef void (APIENTRYP PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target);\ntypedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params);\ntypedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBindFragDataLocationIndexed (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);\nGLAPI GLint APIENTRY glGetFragDataIndex (GLuint program, const GLchar *name);\nGLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers);\nGLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers);\nGLAPI GLboolean APIENTRY glIsSampler (GLuint sampler);\nGLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler);\nGLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param);\nGLAPI void APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param);\nGLAPI void APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param);\nGLAPI void APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param);\nGLAPI void APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param);\nGLAPI void APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param);\nGLAPI void APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params);\nGLAPI void APIENTRY glQueryCounter (GLuint id, GLenum target);\nGLAPI void APIENTRY glGetQueryObjecti64v (GLuint id, GLenum pname, GLint64 *params);\nGLAPI void APIENTRY glGetQueryObjectui64v (GLuint id, GLenum pname, GLuint64 *params);\nGLAPI void APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor);\nGLAPI void APIENTRY glVertexAttribP1ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);\nGLAPI void APIENTRY glVertexAttribP1uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);\nGLAPI void APIENTRY glVertexAttribP2ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);\nGLAPI void APIENTRY glVertexAttribP2uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);\nGLAPI void APIENTRY glVertexAttribP3ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);\nGLAPI void APIENTRY glVertexAttribP3uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);\nGLAPI void APIENTRY glVertexAttribP4ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);\nGLAPI void APIENTRY glVertexAttribP4uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);\n#endif\n#endif /* GL_VERSION_3_3 */\n\n#ifndef GL_VERSION_4_0\n#define GL_VERSION_4_0 1\n#define GL_SAMPLE_SHADING                 0x8C36\n#define GL_MIN_SAMPLE_SHADING_VALUE       0x8C37\n#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E\n#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F\n#define GL_TEXTURE_CUBE_MAP_ARRAY         0x9009\n#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A\n#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY   0x900B\n#define GL_SAMPLER_CUBE_MAP_ARRAY         0x900C\n#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW  0x900D\n#define GL_INT_SAMPLER_CUBE_MAP_ARRAY     0x900E\n#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F\n#define GL_DRAW_INDIRECT_BUFFER           0x8F3F\n#define GL_DRAW_INDIRECT_BUFFER_BINDING   0x8F43\n#define GL_GEOMETRY_SHADER_INVOCATIONS    0x887F\n#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A\n#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B\n#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C\n#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D\n#define GL_MAX_VERTEX_STREAMS             0x8E71\n#define GL_DOUBLE_VEC2                    0x8FFC\n#define GL_DOUBLE_VEC3                    0x8FFD\n#define GL_DOUBLE_VEC4                    0x8FFE\n#define GL_DOUBLE_MAT2                    0x8F46\n#define GL_DOUBLE_MAT3                    0x8F47\n#define GL_DOUBLE_MAT4                    0x8F48\n#define GL_DOUBLE_MAT2x3                  0x8F49\n#define GL_DOUBLE_MAT2x4                  0x8F4A\n#define GL_DOUBLE_MAT3x2                  0x8F4B\n#define GL_DOUBLE_MAT3x4                  0x8F4C\n#define GL_DOUBLE_MAT4x2                  0x8F4D\n#define GL_DOUBLE_MAT4x3                  0x8F4E\n#define GL_ACTIVE_SUBROUTINES             0x8DE5\n#define GL_ACTIVE_SUBROUTINE_UNIFORMS     0x8DE6\n#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47\n#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH   0x8E48\n#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49\n#define GL_MAX_SUBROUTINES                0x8DE7\n#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8\n#define GL_NUM_COMPATIBLE_SUBROUTINES     0x8E4A\n#define GL_COMPATIBLE_SUBROUTINES         0x8E4B\n#define GL_PATCHES                        0x000E\n#define GL_PATCH_VERTICES                 0x8E72\n#define GL_PATCH_DEFAULT_INNER_LEVEL      0x8E73\n#define GL_PATCH_DEFAULT_OUTER_LEVEL      0x8E74\n#define GL_TESS_CONTROL_OUTPUT_VERTICES   0x8E75\n#define GL_TESS_GEN_MODE                  0x8E76\n#define GL_TESS_GEN_SPACING               0x8E77\n#define GL_TESS_GEN_VERTEX_ORDER          0x8E78\n#define GL_TESS_GEN_POINT_MODE            0x8E79\n#define GL_ISOLINES                       0x8E7A\n#define GL_FRACTIONAL_ODD                 0x8E7B\n#define GL_FRACTIONAL_EVEN                0x8E7C\n#define GL_MAX_PATCH_VERTICES             0x8E7D\n#define GL_MAX_TESS_GEN_LEVEL             0x8E7E\n#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F\n#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80\n#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81\n#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82\n#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83\n#define GL_MAX_TESS_PATCH_COMPONENTS      0x8E84\n#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85\n#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86\n#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89\n#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A\n#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C\n#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D\n#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E\n#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F\n#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0\n#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1\n#define GL_TESS_EVALUATION_SHADER         0x8E87\n#define GL_TESS_CONTROL_SHADER            0x8E88\n#define GL_TRANSFORM_FEEDBACK             0x8E22\n#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23\n#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24\n#define GL_TRANSFORM_FEEDBACK_BINDING     0x8E25\n#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70\ntypedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLfloat value);\ntypedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode);\ntypedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);\ntypedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst);\ntypedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);\ntypedef void (APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect);\ntypedef void (APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect);\ntypedef void (APIENTRYP PFNGLUNIFORM1DPROC) (GLint location, GLdouble x);\ntypedef void (APIENTRYP PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y);\ntypedef void (APIENTRYP PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z);\ntypedef void (APIENTRYP PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);\ntypedef void (APIENTRYP PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble *params);\ntypedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name);\ntypedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name);\ntypedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values);\ntypedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);\ntypedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);\ntypedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices);\ntypedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params);\ntypedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values);\ntypedef void (APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value);\ntypedef void (APIENTRYP PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat *values);\ntypedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id);\ntypedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids);\ntypedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids);\ntypedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id);\ntypedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void);\ntypedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void);\ntypedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id);\ntypedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream);\ntypedef void (APIENTRYP PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id);\ntypedef void (APIENTRYP PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index);\ntypedef void (APIENTRYP PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glMinSampleShading (GLfloat value);\nGLAPI void APIENTRY glBlendEquationi (GLuint buf, GLenum mode);\nGLAPI void APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha);\nGLAPI void APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst);\nGLAPI void APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);\nGLAPI void APIENTRY glDrawArraysIndirect (GLenum mode, const void *indirect);\nGLAPI void APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect);\nGLAPI void APIENTRY glUniform1d (GLint location, GLdouble x);\nGLAPI void APIENTRY glUniform2d (GLint location, GLdouble x, GLdouble y);\nGLAPI void APIENTRY glUniform3d (GLint location, GLdouble x, GLdouble y, GLdouble z);\nGLAPI void APIENTRY glUniform4d (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);\nGLAPI void APIENTRY glUniform1dv (GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glUniform2dv (GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glUniform3dv (GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glUniform4dv (GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix2x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix2x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix3x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix3x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix4x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glUniformMatrix4x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *params);\nGLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name);\nGLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name);\nGLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values);\nGLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);\nGLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);\nGLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices);\nGLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params);\nGLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values);\nGLAPI void APIENTRY glPatchParameteri (GLenum pname, GLint value);\nGLAPI void APIENTRY glPatchParameterfv (GLenum pname, const GLfloat *values);\nGLAPI void APIENTRY glBindTransformFeedback (GLenum target, GLuint id);\nGLAPI void APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids);\nGLAPI void APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids);\nGLAPI GLboolean APIENTRY glIsTransformFeedback (GLuint id);\nGLAPI void APIENTRY glPauseTransformFeedback (void);\nGLAPI void APIENTRY glResumeTransformFeedback (void);\nGLAPI void APIENTRY glDrawTransformFeedback (GLenum mode, GLuint id);\nGLAPI void APIENTRY glDrawTransformFeedbackStream (GLenum mode, GLuint id, GLuint stream);\nGLAPI void APIENTRY glBeginQueryIndexed (GLenum target, GLuint index, GLuint id);\nGLAPI void APIENTRY glEndQueryIndexed (GLenum target, GLuint index);\nGLAPI void APIENTRY glGetQueryIndexediv (GLenum target, GLuint index, GLenum pname, GLint *params);\n#endif\n#endif /* GL_VERSION_4_0 */\n\n#ifndef GL_VERSION_4_1\n#define GL_VERSION_4_1 1\n#define GL_FIXED                          0x140C\n#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A\n#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B\n#define GL_LOW_FLOAT                      0x8DF0\n#define GL_MEDIUM_FLOAT                   0x8DF1\n#define GL_HIGH_FLOAT                     0x8DF2\n#define GL_LOW_INT                        0x8DF3\n#define GL_MEDIUM_INT                     0x8DF4\n#define GL_HIGH_INT                       0x8DF5\n#define GL_SHADER_COMPILER                0x8DFA\n#define GL_SHADER_BINARY_FORMATS          0x8DF8\n#define GL_NUM_SHADER_BINARY_FORMATS      0x8DF9\n#define GL_MAX_VERTEX_UNIFORM_VECTORS     0x8DFB\n#define GL_MAX_VARYING_VECTORS            0x8DFC\n#define GL_MAX_FRAGMENT_UNIFORM_VECTORS   0x8DFD\n#define GL_RGB565                         0x8D62\n#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257\n#define GL_PROGRAM_BINARY_LENGTH          0x8741\n#define GL_NUM_PROGRAM_BINARY_FORMATS     0x87FE\n#define GL_PROGRAM_BINARY_FORMATS         0x87FF\n#define GL_VERTEX_SHADER_BIT              0x00000001\n#define GL_FRAGMENT_SHADER_BIT            0x00000002\n#define GL_GEOMETRY_SHADER_BIT            0x00000004\n#define GL_TESS_CONTROL_SHADER_BIT        0x00000008\n#define GL_TESS_EVALUATION_SHADER_BIT     0x00000010\n#define GL_ALL_SHADER_BITS                0xFFFFFFFF\n#define GL_PROGRAM_SEPARABLE              0x8258\n#define GL_ACTIVE_PROGRAM                 0x8259\n#define GL_PROGRAM_PIPELINE_BINDING       0x825A\n#define GL_MAX_VIEWPORTS                  0x825B\n#define GL_VIEWPORT_SUBPIXEL_BITS         0x825C\n#define GL_VIEWPORT_BOUNDS_RANGE          0x825D\n#define GL_LAYER_PROVOKING_VERTEX         0x825E\n#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F\n#define GL_UNDEFINED_VERTEX               0x8260\ntypedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void);\ntypedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length);\ntypedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);\ntypedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f);\ntypedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d);\ntypedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);\ntypedef void (APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);\ntypedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value);\ntypedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program);\ntypedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program);\ntypedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar *const*strings);\ntypedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline);\ntypedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines);\ntypedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines);\ntypedef GLboolean (APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline);\ntypedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble v0);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline);\ntypedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble *params);\ntypedef void (APIENTRYP PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);\ntypedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v);\ntypedef void (APIENTRYP PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v);\ntypedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLdouble n, GLdouble f);\ntypedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data);\ntypedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glReleaseShaderCompiler (void);\nGLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length);\nGLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);\nGLAPI void APIENTRY glDepthRangef (GLfloat n, GLfloat f);\nGLAPI void APIENTRY glClearDepthf (GLfloat d);\nGLAPI void APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);\nGLAPI void APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);\nGLAPI void APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value);\nGLAPI void APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program);\nGLAPI void APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program);\nGLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar *const*strings);\nGLAPI void APIENTRY glBindProgramPipeline (GLuint pipeline);\nGLAPI void APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines);\nGLAPI void APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines);\nGLAPI GLboolean APIENTRY glIsProgramPipeline (GLuint pipeline);\nGLAPI void APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params);\nGLAPI void APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0);\nGLAPI void APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0);\nGLAPI void APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniform1d (GLuint program, GLint location, GLdouble v0);\nGLAPI void APIENTRY glProgramUniform1dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0);\nGLAPI void APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1);\nGLAPI void APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1);\nGLAPI void APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniform2d (GLuint program, GLint location, GLdouble v0, GLdouble v1);\nGLAPI void APIENTRY glProgramUniform2dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1);\nGLAPI void APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);\nGLAPI void APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);\nGLAPI void APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniform3d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2);\nGLAPI void APIENTRY glProgramUniform3dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);\nGLAPI void APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);\nGLAPI void APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);\nGLAPI void APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniform4d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);\nGLAPI void APIENTRY glProgramUniform4dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);\nGLAPI void APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix2x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix3x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix2x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix4x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix3x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix4x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glValidateProgramPipeline (GLuint pipeline);\nGLAPI void APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);\nGLAPI void APIENTRY glVertexAttribL1d (GLuint index, GLdouble x);\nGLAPI void APIENTRY glVertexAttribL2d (GLuint index, GLdouble x, GLdouble y);\nGLAPI void APIENTRY glVertexAttribL3d (GLuint index, GLdouble x, GLdouble y, GLdouble z);\nGLAPI void APIENTRY glVertexAttribL4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);\nGLAPI void APIENTRY glVertexAttribL1dv (GLuint index, const GLdouble *v);\nGLAPI void APIENTRY glVertexAttribL2dv (GLuint index, const GLdouble *v);\nGLAPI void APIENTRY glVertexAttribL3dv (GLuint index, const GLdouble *v);\nGLAPI void APIENTRY glVertexAttribL4dv (GLuint index, const GLdouble *v);\nGLAPI void APIENTRY glVertexAttribLPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);\nGLAPI void APIENTRY glGetVertexAttribLdv (GLuint index, GLenum pname, GLdouble *params);\nGLAPI void APIENTRY glViewportArrayv (GLuint first, GLsizei count, const GLfloat *v);\nGLAPI void APIENTRY glViewportIndexedf (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);\nGLAPI void APIENTRY glViewportIndexedfv (GLuint index, const GLfloat *v);\nGLAPI void APIENTRY glScissorArrayv (GLuint first, GLsizei count, const GLint *v);\nGLAPI void APIENTRY glScissorIndexed (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glScissorIndexedv (GLuint index, const GLint *v);\nGLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLdouble *v);\nGLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLdouble n, GLdouble f);\nGLAPI void APIENTRY glGetFloati_v (GLenum target, GLuint index, GLfloat *data);\nGLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data);\n#endif\n#endif /* GL_VERSION_4_1 */\n\n#ifndef GL_VERSION_4_2\n#define GL_VERSION_4_2 1\n#define GL_COPY_READ_BUFFER_BINDING       0x8F36\n#define GL_COPY_WRITE_BUFFER_BINDING      0x8F37\n#define GL_TRANSFORM_FEEDBACK_ACTIVE      0x8E24\n#define GL_TRANSFORM_FEEDBACK_PAUSED      0x8E23\n#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH  0x9127\n#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128\n#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH  0x9129\n#define GL_UNPACK_COMPRESSED_BLOCK_SIZE   0x912A\n#define GL_PACK_COMPRESSED_BLOCK_WIDTH    0x912B\n#define GL_PACK_COMPRESSED_BLOCK_HEIGHT   0x912C\n#define GL_PACK_COMPRESSED_BLOCK_DEPTH    0x912D\n#define GL_PACK_COMPRESSED_BLOCK_SIZE     0x912E\n#define GL_NUM_SAMPLE_COUNTS              0x9380\n#define GL_MIN_MAP_BUFFER_ALIGNMENT       0x90BC\n#define GL_ATOMIC_COUNTER_BUFFER          0x92C0\n#define GL_ATOMIC_COUNTER_BUFFER_BINDING  0x92C1\n#define GL_ATOMIC_COUNTER_BUFFER_START    0x92C2\n#define GL_ATOMIC_COUNTER_BUFFER_SIZE     0x92C3\n#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4\n#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5\n#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6\n#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7\n#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8\n#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9\n#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA\n#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB\n#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC\n#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD\n#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE\n#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF\n#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0\n#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1\n#define GL_MAX_VERTEX_ATOMIC_COUNTERS     0x92D2\n#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3\n#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4\n#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS   0x92D5\n#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS   0x92D6\n#define GL_MAX_COMBINED_ATOMIC_COUNTERS   0x92D7\n#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8\n#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC\n#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS  0x92D9\n#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA\n#define GL_UNSIGNED_INT_ATOMIC_COUNTER    0x92DB\n#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001\n#define GL_ELEMENT_ARRAY_BARRIER_BIT      0x00000002\n#define GL_UNIFORM_BARRIER_BIT            0x00000004\n#define GL_TEXTURE_FETCH_BARRIER_BIT      0x00000008\n#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020\n#define GL_COMMAND_BARRIER_BIT            0x00000040\n#define GL_PIXEL_BUFFER_BARRIER_BIT       0x00000080\n#define GL_TEXTURE_UPDATE_BARRIER_BIT     0x00000100\n#define GL_BUFFER_UPDATE_BARRIER_BIT      0x00000200\n#define GL_FRAMEBUFFER_BARRIER_BIT        0x00000400\n#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800\n#define GL_ATOMIC_COUNTER_BARRIER_BIT     0x00001000\n#define GL_ALL_BARRIER_BITS               0xFFFFFFFF\n#define GL_MAX_IMAGE_UNITS                0x8F38\n#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39\n#define GL_IMAGE_BINDING_NAME             0x8F3A\n#define GL_IMAGE_BINDING_LEVEL            0x8F3B\n#define GL_IMAGE_BINDING_LAYERED          0x8F3C\n#define GL_IMAGE_BINDING_LAYER            0x8F3D\n#define GL_IMAGE_BINDING_ACCESS           0x8F3E\n#define GL_IMAGE_1D                       0x904C\n#define GL_IMAGE_2D                       0x904D\n#define GL_IMAGE_3D                       0x904E\n#define GL_IMAGE_2D_RECT                  0x904F\n#define GL_IMAGE_CUBE                     0x9050\n#define GL_IMAGE_BUFFER                   0x9051\n#define GL_IMAGE_1D_ARRAY                 0x9052\n#define GL_IMAGE_2D_ARRAY                 0x9053\n#define GL_IMAGE_CUBE_MAP_ARRAY           0x9054\n#define GL_IMAGE_2D_MULTISAMPLE           0x9055\n#define GL_IMAGE_2D_MULTISAMPLE_ARRAY     0x9056\n#define GL_INT_IMAGE_1D                   0x9057\n#define GL_INT_IMAGE_2D                   0x9058\n#define GL_INT_IMAGE_3D                   0x9059\n#define GL_INT_IMAGE_2D_RECT              0x905A\n#define GL_INT_IMAGE_CUBE                 0x905B\n#define GL_INT_IMAGE_BUFFER               0x905C\n#define GL_INT_IMAGE_1D_ARRAY             0x905D\n#define GL_INT_IMAGE_2D_ARRAY             0x905E\n#define GL_INT_IMAGE_CUBE_MAP_ARRAY       0x905F\n#define GL_INT_IMAGE_2D_MULTISAMPLE       0x9060\n#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061\n#define GL_UNSIGNED_INT_IMAGE_1D          0x9062\n#define GL_UNSIGNED_INT_IMAGE_2D          0x9063\n#define GL_UNSIGNED_INT_IMAGE_3D          0x9064\n#define GL_UNSIGNED_INT_IMAGE_2D_RECT     0x9065\n#define GL_UNSIGNED_INT_IMAGE_CUBE        0x9066\n#define GL_UNSIGNED_INT_IMAGE_BUFFER      0x9067\n#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY    0x9068\n#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY    0x9069\n#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A\n#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B\n#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C\n#define GL_MAX_IMAGE_SAMPLES              0x906D\n#define GL_IMAGE_BINDING_FORMAT           0x906E\n#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7\n#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8\n#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9\n#define GL_MAX_VERTEX_IMAGE_UNIFORMS      0x90CA\n#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB\n#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC\n#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS    0x90CD\n#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS    0x90CE\n#define GL_MAX_COMBINED_IMAGE_UNIFORMS    0x90CF\n#define GL_COMPRESSED_RGBA_BPTC_UNORM     0x8E8C\n#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D\n#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E\n#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F\n#define GL_TEXTURE_IMMUTABLE_FORMAT       0x912F\ntypedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);\ntypedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance);\ntypedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);\ntypedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint *params);\ntypedef void (APIENTRYP PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);\ntypedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers);\ntypedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);\ntypedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);\ntypedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei instancecount);\ntypedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);\nGLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance);\nGLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);\nGLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint *params);\nGLAPI void APIENTRY glGetActiveAtomicCounterBufferiv (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params);\nGLAPI void APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);\nGLAPI void APIENTRY glMemoryBarrier (GLbitfield barriers);\nGLAPI void APIENTRY glTexStorage1D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);\nGLAPI void APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);\nGLAPI void APIENTRY glDrawTransformFeedbackInstanced (GLenum mode, GLuint id, GLsizei instancecount);\nGLAPI void APIENTRY glDrawTransformFeedbackStreamInstanced (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount);\n#endif\n#endif /* GL_VERSION_4_2 */\n\n#ifndef GL_VERSION_4_3\n#define GL_VERSION_4_3 1\ntypedef void (APIENTRY  *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);\n#define GL_NUM_SHADING_LANGUAGE_VERSIONS  0x82E9\n#define GL_VERTEX_ATTRIB_ARRAY_LONG       0x874E\n#define GL_COMPRESSED_RGB8_ETC2           0x9274\n#define GL_COMPRESSED_SRGB8_ETC2          0x9275\n#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276\n#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277\n#define GL_COMPRESSED_RGBA8_ETC2_EAC      0x9278\n#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279\n#define GL_COMPRESSED_R11_EAC             0x9270\n#define GL_COMPRESSED_SIGNED_R11_EAC      0x9271\n#define GL_COMPRESSED_RG11_EAC            0x9272\n#define GL_COMPRESSED_SIGNED_RG11_EAC     0x9273\n#define GL_PRIMITIVE_RESTART_FIXED_INDEX  0x8D69\n#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A\n#define GL_MAX_ELEMENT_INDEX              0x8D6B\n#define GL_COMPUTE_SHADER                 0x91B9\n#define GL_MAX_COMPUTE_UNIFORM_BLOCKS     0x91BB\n#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC\n#define GL_MAX_COMPUTE_IMAGE_UNIFORMS     0x91BD\n#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262\n#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263\n#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264\n#define GL_MAX_COMPUTE_ATOMIC_COUNTERS    0x8265\n#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266\n#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB\n#define GL_MAX_COMPUTE_WORK_GROUP_COUNT   0x91BE\n#define GL_MAX_COMPUTE_WORK_GROUP_SIZE    0x91BF\n#define GL_COMPUTE_WORK_GROUP_SIZE        0x8267\n#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC\n#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED\n#define GL_DISPATCH_INDIRECT_BUFFER       0x90EE\n#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF\n#define GL_COMPUTE_SHADER_BIT             0x00000020\n#define GL_DEBUG_OUTPUT_SYNCHRONOUS       0x8242\n#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243\n#define GL_DEBUG_CALLBACK_FUNCTION        0x8244\n#define GL_DEBUG_CALLBACK_USER_PARAM      0x8245\n#define GL_DEBUG_SOURCE_API               0x8246\n#define GL_DEBUG_SOURCE_WINDOW_SYSTEM     0x8247\n#define GL_DEBUG_SOURCE_SHADER_COMPILER   0x8248\n#define GL_DEBUG_SOURCE_THIRD_PARTY       0x8249\n#define GL_DEBUG_SOURCE_APPLICATION       0x824A\n#define GL_DEBUG_SOURCE_OTHER             0x824B\n#define GL_DEBUG_TYPE_ERROR               0x824C\n#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D\n#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR  0x824E\n#define GL_DEBUG_TYPE_PORTABILITY         0x824F\n#define GL_DEBUG_TYPE_PERFORMANCE         0x8250\n#define GL_DEBUG_TYPE_OTHER               0x8251\n#define GL_MAX_DEBUG_MESSAGE_LENGTH       0x9143\n#define GL_MAX_DEBUG_LOGGED_MESSAGES      0x9144\n#define GL_DEBUG_LOGGED_MESSAGES          0x9145\n#define GL_DEBUG_SEVERITY_HIGH            0x9146\n#define GL_DEBUG_SEVERITY_MEDIUM          0x9147\n#define GL_DEBUG_SEVERITY_LOW             0x9148\n#define GL_DEBUG_TYPE_MARKER              0x8268\n#define GL_DEBUG_TYPE_PUSH_GROUP          0x8269\n#define GL_DEBUG_TYPE_POP_GROUP           0x826A\n#define GL_DEBUG_SEVERITY_NOTIFICATION    0x826B\n#define GL_MAX_DEBUG_GROUP_STACK_DEPTH    0x826C\n#define GL_DEBUG_GROUP_STACK_DEPTH        0x826D\n#define GL_BUFFER                         0x82E0\n#define GL_SHADER                         0x82E1\n#define GL_PROGRAM                        0x82E2\n#define GL_QUERY                          0x82E3\n#define GL_PROGRAM_PIPELINE               0x82E4\n#define GL_SAMPLER                        0x82E6\n#define GL_MAX_LABEL_LENGTH               0x82E8\n#define GL_DEBUG_OUTPUT                   0x92E0\n#define GL_CONTEXT_FLAG_DEBUG_BIT         0x00000002\n#define GL_MAX_UNIFORM_LOCATIONS          0x826E\n#define GL_FRAMEBUFFER_DEFAULT_WIDTH      0x9310\n#define GL_FRAMEBUFFER_DEFAULT_HEIGHT     0x9311\n#define GL_FRAMEBUFFER_DEFAULT_LAYERS     0x9312\n#define GL_FRAMEBUFFER_DEFAULT_SAMPLES    0x9313\n#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314\n#define GL_MAX_FRAMEBUFFER_WIDTH          0x9315\n#define GL_MAX_FRAMEBUFFER_HEIGHT         0x9316\n#define GL_MAX_FRAMEBUFFER_LAYERS         0x9317\n#define GL_MAX_FRAMEBUFFER_SAMPLES        0x9318\n#define GL_INTERNALFORMAT_SUPPORTED       0x826F\n#define GL_INTERNALFORMAT_PREFERRED       0x8270\n#define GL_INTERNALFORMAT_RED_SIZE        0x8271\n#define GL_INTERNALFORMAT_GREEN_SIZE      0x8272\n#define GL_INTERNALFORMAT_BLUE_SIZE       0x8273\n#define GL_INTERNALFORMAT_ALPHA_SIZE      0x8274\n#define GL_INTERNALFORMAT_DEPTH_SIZE      0x8275\n#define GL_INTERNALFORMAT_STENCIL_SIZE    0x8276\n#define GL_INTERNALFORMAT_SHARED_SIZE     0x8277\n#define GL_INTERNALFORMAT_RED_TYPE        0x8278\n#define GL_INTERNALFORMAT_GREEN_TYPE      0x8279\n#define GL_INTERNALFORMAT_BLUE_TYPE       0x827A\n#define GL_INTERNALFORMAT_ALPHA_TYPE      0x827B\n#define GL_INTERNALFORMAT_DEPTH_TYPE      0x827C\n#define GL_INTERNALFORMAT_STENCIL_TYPE    0x827D\n#define GL_MAX_WIDTH                      0x827E\n#define GL_MAX_HEIGHT                     0x827F\n#define GL_MAX_DEPTH                      0x8280\n#define GL_MAX_LAYERS                     0x8281\n#define GL_MAX_COMBINED_DIMENSIONS        0x8282\n#define GL_COLOR_COMPONENTS               0x8283\n#define GL_DEPTH_COMPONENTS               0x8284\n#define GL_STENCIL_COMPONENTS             0x8285\n#define GL_COLOR_RENDERABLE               0x8286\n#define GL_DEPTH_RENDERABLE               0x8287\n#define GL_STENCIL_RENDERABLE             0x8288\n#define GL_FRAMEBUFFER_RENDERABLE         0x8289\n#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A\n#define GL_FRAMEBUFFER_BLEND              0x828B\n#define GL_READ_PIXELS                    0x828C\n#define GL_READ_PIXELS_FORMAT             0x828D\n#define GL_READ_PIXELS_TYPE               0x828E\n#define GL_TEXTURE_IMAGE_FORMAT           0x828F\n#define GL_TEXTURE_IMAGE_TYPE             0x8290\n#define GL_GET_TEXTURE_IMAGE_FORMAT       0x8291\n#define GL_GET_TEXTURE_IMAGE_TYPE         0x8292\n#define GL_MIPMAP                         0x8293\n#define GL_MANUAL_GENERATE_MIPMAP         0x8294\n#define GL_AUTO_GENERATE_MIPMAP           0x8295\n#define GL_COLOR_ENCODING                 0x8296\n#define GL_SRGB_READ                      0x8297\n#define GL_SRGB_WRITE                     0x8298\n#define GL_FILTER                         0x829A\n#define GL_VERTEX_TEXTURE                 0x829B\n#define GL_TESS_CONTROL_TEXTURE           0x829C\n#define GL_TESS_EVALUATION_TEXTURE        0x829D\n#define GL_GEOMETRY_TEXTURE               0x829E\n#define GL_FRAGMENT_TEXTURE               0x829F\n#define GL_COMPUTE_TEXTURE                0x82A0\n#define GL_TEXTURE_SHADOW                 0x82A1\n#define GL_TEXTURE_GATHER                 0x82A2\n#define GL_TEXTURE_GATHER_SHADOW          0x82A3\n#define GL_SHADER_IMAGE_LOAD              0x82A4\n#define GL_SHADER_IMAGE_STORE             0x82A5\n#define GL_SHADER_IMAGE_ATOMIC            0x82A6\n#define GL_IMAGE_TEXEL_SIZE               0x82A7\n#define GL_IMAGE_COMPATIBILITY_CLASS      0x82A8\n#define GL_IMAGE_PIXEL_FORMAT             0x82A9\n#define GL_IMAGE_PIXEL_TYPE               0x82AA\n#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC\n#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD\n#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE\n#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF\n#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1\n#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2\n#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE  0x82B3\n#define GL_CLEAR_BUFFER                   0x82B4\n#define GL_TEXTURE_VIEW                   0x82B5\n#define GL_VIEW_COMPATIBILITY_CLASS       0x82B6\n#define GL_FULL_SUPPORT                   0x82B7\n#define GL_CAVEAT_SUPPORT                 0x82B8\n#define GL_IMAGE_CLASS_4_X_32             0x82B9\n#define GL_IMAGE_CLASS_2_X_32             0x82BA\n#define GL_IMAGE_CLASS_1_X_32             0x82BB\n#define GL_IMAGE_CLASS_4_X_16             0x82BC\n#define GL_IMAGE_CLASS_2_X_16             0x82BD\n#define GL_IMAGE_CLASS_1_X_16             0x82BE\n#define GL_IMAGE_CLASS_4_X_8              0x82BF\n#define GL_IMAGE_CLASS_2_X_8              0x82C0\n#define GL_IMAGE_CLASS_1_X_8              0x82C1\n#define GL_IMAGE_CLASS_11_11_10           0x82C2\n#define GL_IMAGE_CLASS_10_10_10_2         0x82C3\n#define GL_VIEW_CLASS_128_BITS            0x82C4\n#define GL_VIEW_CLASS_96_BITS             0x82C5\n#define GL_VIEW_CLASS_64_BITS             0x82C6\n#define GL_VIEW_CLASS_48_BITS             0x82C7\n#define GL_VIEW_CLASS_32_BITS             0x82C8\n#define GL_VIEW_CLASS_24_BITS             0x82C9\n#define GL_VIEW_CLASS_16_BITS             0x82CA\n#define GL_VIEW_CLASS_8_BITS              0x82CB\n#define GL_VIEW_CLASS_S3TC_DXT1_RGB       0x82CC\n#define GL_VIEW_CLASS_S3TC_DXT1_RGBA      0x82CD\n#define GL_VIEW_CLASS_S3TC_DXT3_RGBA      0x82CE\n#define GL_VIEW_CLASS_S3TC_DXT5_RGBA      0x82CF\n#define GL_VIEW_CLASS_RGTC1_RED           0x82D0\n#define GL_VIEW_CLASS_RGTC2_RG            0x82D1\n#define GL_VIEW_CLASS_BPTC_UNORM          0x82D2\n#define GL_VIEW_CLASS_BPTC_FLOAT          0x82D3\n#define GL_UNIFORM                        0x92E1\n#define GL_UNIFORM_BLOCK                  0x92E2\n#define GL_PROGRAM_INPUT                  0x92E3\n#define GL_PROGRAM_OUTPUT                 0x92E4\n#define GL_BUFFER_VARIABLE                0x92E5\n#define GL_SHADER_STORAGE_BLOCK           0x92E6\n#define GL_VERTEX_SUBROUTINE              0x92E8\n#define GL_TESS_CONTROL_SUBROUTINE        0x92E9\n#define GL_TESS_EVALUATION_SUBROUTINE     0x92EA\n#define GL_GEOMETRY_SUBROUTINE            0x92EB\n#define GL_FRAGMENT_SUBROUTINE            0x92EC\n#define GL_COMPUTE_SUBROUTINE             0x92ED\n#define GL_VERTEX_SUBROUTINE_UNIFORM      0x92EE\n#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF\n#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0\n#define GL_GEOMETRY_SUBROUTINE_UNIFORM    0x92F1\n#define GL_FRAGMENT_SUBROUTINE_UNIFORM    0x92F2\n#define GL_COMPUTE_SUBROUTINE_UNIFORM     0x92F3\n#define GL_TRANSFORM_FEEDBACK_VARYING     0x92F4\n#define GL_ACTIVE_RESOURCES               0x92F5\n#define GL_MAX_NAME_LENGTH                0x92F6\n#define GL_MAX_NUM_ACTIVE_VARIABLES       0x92F7\n#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8\n#define GL_NAME_LENGTH                    0x92F9\n#define GL_TYPE                           0x92FA\n#define GL_ARRAY_SIZE                     0x92FB\n#define GL_OFFSET                         0x92FC\n#define GL_BLOCK_INDEX                    0x92FD\n#define GL_ARRAY_STRIDE                   0x92FE\n#define GL_MATRIX_STRIDE                  0x92FF\n#define GL_IS_ROW_MAJOR                   0x9300\n#define GL_ATOMIC_COUNTER_BUFFER_INDEX    0x9301\n#define GL_BUFFER_BINDING                 0x9302\n#define GL_BUFFER_DATA_SIZE               0x9303\n#define GL_NUM_ACTIVE_VARIABLES           0x9304\n#define GL_ACTIVE_VARIABLES               0x9305\n#define GL_REFERENCED_BY_VERTEX_SHADER    0x9306\n#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307\n#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308\n#define GL_REFERENCED_BY_GEOMETRY_SHADER  0x9309\n#define GL_REFERENCED_BY_FRAGMENT_SHADER  0x930A\n#define GL_REFERENCED_BY_COMPUTE_SHADER   0x930B\n#define GL_TOP_LEVEL_ARRAY_SIZE           0x930C\n#define GL_TOP_LEVEL_ARRAY_STRIDE         0x930D\n#define GL_LOCATION                       0x930E\n#define GL_LOCATION_INDEX                 0x930F\n#define GL_IS_PER_PATCH                   0x92E7\n#define GL_SHADER_STORAGE_BUFFER          0x90D2\n#define GL_SHADER_STORAGE_BUFFER_BINDING  0x90D3\n#define GL_SHADER_STORAGE_BUFFER_START    0x90D4\n#define GL_SHADER_STORAGE_BUFFER_SIZE     0x90D5\n#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6\n#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7\n#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8\n#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9\n#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA\n#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB\n#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC\n#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD\n#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE  0x90DE\n#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF\n#define GL_SHADER_STORAGE_BARRIER_BIT     0x00002000\n#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39\n#define GL_DEPTH_STENCIL_TEXTURE_MODE     0x90EA\n#define GL_TEXTURE_BUFFER_OFFSET          0x919D\n#define GL_TEXTURE_BUFFER_SIZE            0x919E\n#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F\n#define GL_TEXTURE_VIEW_MIN_LEVEL         0x82DB\n#define GL_TEXTURE_VIEW_NUM_LEVELS        0x82DC\n#define GL_TEXTURE_VIEW_MIN_LAYER         0x82DD\n#define GL_TEXTURE_VIEW_NUM_LAYERS        0x82DE\n#define GL_TEXTURE_IMMUTABLE_LEVELS       0x82DF\n#define GL_VERTEX_ATTRIB_BINDING          0x82D4\n#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET  0x82D5\n#define GL_VERTEX_BINDING_DIVISOR         0x82D6\n#define GL_VERTEX_BINDING_OFFSET          0x82D7\n#define GL_VERTEX_BINDING_STRIDE          0x82D8\n#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9\n#define GL_MAX_VERTEX_ATTRIB_BINDINGS     0x82DA\n#define GL_VERTEX_BINDING_BUFFER          0x8F4F\ntypedef void (APIENTRYP PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data);\ntypedef void (APIENTRYP PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);\ntypedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);\ntypedef void (APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect);\ntypedef void (APIENTRYP PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint64 *params);\ntypedef void (APIENTRYP PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);\ntypedef void (APIENTRYP PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level);\ntypedef void (APIENTRYP PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);\ntypedef void (APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer);\ntypedef void (APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments);\ntypedef void (APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride);\ntypedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride);\ntypedef void (APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params);\ntypedef GLuint (APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name);\ntypedef void (APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);\ntypedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLint *params);\ntypedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name);\ntypedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name);\ntypedef void (APIENTRYP PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding);\ntypedef void (APIENTRYP PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);\ntypedef void (APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);\ntypedef void (APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);\ntypedef void (APIENTRYP PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);\ntypedef void (APIENTRYP PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex);\ntypedef void (APIENTRYP PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor);\ntypedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);\ntypedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);\ntypedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam);\ntypedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);\ntypedef void (APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message);\ntypedef void (APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void);\ntypedef void (APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);\ntypedef void (APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);\ntypedef void (APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label);\ntypedef void (APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glClearBufferData (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data);\nGLAPI void APIENTRY glClearBufferSubData (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);\nGLAPI void APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);\nGLAPI void APIENTRY glDispatchComputeIndirect (GLintptr indirect);\nGLAPI void APIENTRY glCopyImageSubData (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);\nGLAPI void APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param);\nGLAPI void APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetInternalformati64v (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint64 *params);\nGLAPI void APIENTRY glInvalidateTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);\nGLAPI void APIENTRY glInvalidateTexImage (GLuint texture, GLint level);\nGLAPI void APIENTRY glInvalidateBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr length);\nGLAPI void APIENTRY glInvalidateBufferData (GLuint buffer);\nGLAPI void APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments);\nGLAPI void APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glMultiDrawArraysIndirect (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride);\nGLAPI void APIENTRY glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride);\nGLAPI void APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params);\nGLAPI GLuint APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name);\nGLAPI void APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);\nGLAPI void APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLint *params);\nGLAPI GLint APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name);\nGLAPI GLint APIENTRY glGetProgramResourceLocationIndex (GLuint program, GLenum programInterface, const GLchar *name);\nGLAPI void APIENTRY glShaderStorageBlockBinding (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding);\nGLAPI void APIENTRY glTexBufferRange (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);\nGLAPI void APIENTRY glTexStorage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);\nGLAPI void APIENTRY glTexStorage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);\nGLAPI void APIENTRY glTextureView (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);\nGLAPI void APIENTRY glBindVertexBuffer (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);\nGLAPI void APIENTRY glVertexAttribFormat (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);\nGLAPI void APIENTRY glVertexAttribIFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\nGLAPI void APIENTRY glVertexAttribLFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\nGLAPI void APIENTRY glVertexAttribBinding (GLuint attribindex, GLuint bindingindex);\nGLAPI void APIENTRY glVertexBindingDivisor (GLuint bindingindex, GLuint divisor);\nGLAPI void APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);\nGLAPI void APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);\nGLAPI void APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam);\nGLAPI GLuint APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);\nGLAPI void APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message);\nGLAPI void APIENTRY glPopDebugGroup (void);\nGLAPI void APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);\nGLAPI void APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);\nGLAPI void APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label);\nGLAPI void APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);\n#endif\n#endif /* GL_VERSION_4_3 */\n\n#ifndef GL_VERSION_4_4\n#define GL_VERSION_4_4 1\n#define GL_MAX_VERTEX_ATTRIB_STRIDE       0x82E5\n#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221\n#define GL_TEXTURE_BUFFER_BINDING         0x8C2A\n#define GL_MAP_PERSISTENT_BIT             0x0040\n#define GL_MAP_COHERENT_BIT               0x0080\n#define GL_DYNAMIC_STORAGE_BIT            0x0100\n#define GL_CLIENT_STORAGE_BIT             0x0200\n#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000\n#define GL_BUFFER_IMMUTABLE_STORAGE       0x821F\n#define GL_BUFFER_STORAGE_FLAGS           0x8220\n#define GL_CLEAR_TEXTURE                  0x9365\n#define GL_LOCATION_COMPONENT             0x934A\n#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B\n#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C\n#define GL_QUERY_BUFFER                   0x9192\n#define GL_QUERY_BUFFER_BARRIER_BIT       0x00008000\n#define GL_QUERY_BUFFER_BINDING           0x9193\n#define GL_QUERY_RESULT_NO_WAIT           0x9194\n#define GL_MIRROR_CLAMP_TO_EDGE           0x8743\ntypedef void (APIENTRYP PFNGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags);\ntypedef void (APIENTRYP PFNGLCLEARTEXIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data);\ntypedef void (APIENTRYP PFNGLCLEARTEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);\ntypedef void (APIENTRYP PFNGLBINDBUFFERSBASEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers);\ntypedef void (APIENTRYP PFNGLBINDBUFFERSRANGEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes);\ntypedef void (APIENTRYP PFNGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures);\ntypedef void (APIENTRYP PFNGLBINDSAMPLERSPROC) (GLuint first, GLsizei count, const GLuint *samplers);\ntypedef void (APIENTRYP PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures);\ntypedef void (APIENTRYP PFNGLBINDVERTEXBUFFERSPROC) (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBufferStorage (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags);\nGLAPI void APIENTRY glClearTexImage (GLuint texture, GLint level, GLenum format, GLenum type, const void *data);\nGLAPI void APIENTRY glClearTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);\nGLAPI void APIENTRY glBindBuffersBase (GLenum target, GLuint first, GLsizei count, const GLuint *buffers);\nGLAPI void APIENTRY glBindBuffersRange (GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes);\nGLAPI void APIENTRY glBindTextures (GLuint first, GLsizei count, const GLuint *textures);\nGLAPI void APIENTRY glBindSamplers (GLuint first, GLsizei count, const GLuint *samplers);\nGLAPI void APIENTRY glBindImageTextures (GLuint first, GLsizei count, const GLuint *textures);\nGLAPI void APIENTRY glBindVertexBuffers (GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides);\n#endif\n#endif /* GL_VERSION_4_4 */\n\n#ifndef GL_VERSION_4_5\n#define GL_VERSION_4_5 1\n#define GL_CONTEXT_LOST                   0x0507\n#define GL_NEGATIVE_ONE_TO_ONE            0x935E\n#define GL_ZERO_TO_ONE                    0x935F\n#define GL_CLIP_ORIGIN                    0x935C\n#define GL_CLIP_DEPTH_MODE                0x935D\n#define GL_QUERY_WAIT_INVERTED            0x8E17\n#define GL_QUERY_NO_WAIT_INVERTED         0x8E18\n#define GL_QUERY_BY_REGION_WAIT_INVERTED  0x8E19\n#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A\n#define GL_MAX_CULL_DISTANCES             0x82F9\n#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA\n#define GL_TEXTURE_TARGET                 0x1006\n#define GL_QUERY_TARGET                   0x82EA\n#define GL_GUILTY_CONTEXT_RESET           0x8253\n#define GL_INNOCENT_CONTEXT_RESET         0x8254\n#define GL_UNKNOWN_CONTEXT_RESET          0x8255\n#define GL_RESET_NOTIFICATION_STRATEGY    0x8256\n#define GL_LOSE_CONTEXT_ON_RESET          0x8252\n#define GL_NO_RESET_NOTIFICATION          0x8261\n#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004\n#define GL_CONTEXT_RELEASE_BEHAVIOR       0x82FB\n#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC\ntypedef void (APIENTRYP PFNGLCLIPCONTROLPROC) (GLenum origin, GLenum depth);\ntypedef void (APIENTRYP PFNGLCREATETRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids);\ntypedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) (GLuint xfb, GLuint index, GLuint buffer);\ntypedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);\ntypedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKIVPROC) (GLuint xfb, GLenum pname, GLint *param);\ntypedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint *param);\ntypedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64 *param);\ntypedef void (APIENTRYP PFNGLCREATEBUFFERSPROC) (GLsizei n, GLuint *buffers);\ntypedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags);\ntypedef void (APIENTRYP PFNGLNAMEDBUFFERDATAPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage);\ntypedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data);\ntypedef void (APIENTRYP PFNGLCOPYNAMEDBUFFERSUBDATAPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);\ntypedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data);\ntypedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);\ntypedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERPROC) (GLuint buffer, GLenum access);\ntypedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);\ntypedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFERPROC) (GLuint buffer);\ntypedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);\ntypedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVPROC) (GLuint buffer, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) (GLuint buffer, GLenum pname, GLint64 *params);\ntypedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVPROC) (GLuint buffer, GLenum pname, void **params);\ntypedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data);\ntypedef void (APIENTRYP PFNGLCREATEFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) (GLuint framebuffer, GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) (GLuint framebuffer, GLenum buf);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) (GLuint framebuffer, GLenum src);\ntypedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments);\ntypedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value);\ntypedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value);\ntypedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);\ntypedef void (APIENTRYP PFNGLBLITNAMEDFRAMEBUFFERPROC) (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);\ntypedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) (GLuint framebuffer, GLenum target);\ntypedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) (GLuint framebuffer, GLenum pname, GLint *param);\ntypedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLCREATERENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers);\ntypedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) (GLuint renderbuffer, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLCREATETEXTURESPROC) (GLenum target, GLsizei n, GLuint *textures);\ntypedef void (APIENTRYP PFNGLTEXTUREBUFFERPROC) (GLuint texture, GLenum internalformat, GLuint buffer);\ntypedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEPROC) (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);\ntypedef void (APIENTRYP PFNGLTEXTURESTORAGE1DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width);\ntypedef void (APIENTRYP PFNGLTEXTURESTORAGE2DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLTEXTURESTORAGE3DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);\ntypedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);\ntypedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);\ntypedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);\ntypedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);\ntypedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERFPROC) (GLuint texture, GLenum pname, GLfloat param);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, const GLfloat *param);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERIPROC) (GLuint texture, GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, const GLint *params);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, const GLuint *params);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, const GLint *param);\ntypedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPPROC) (GLuint texture);\ntypedef void (APIENTRYP PFNGLBINDTEXTUREUNITPROC) (GLuint unit, GLuint texture);\ntypedef void (APIENTRYP PFNGLGETTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels);\ntypedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLsizei bufSize, void *pixels);\ntypedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVPROC) (GLuint texture, GLint level, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVPROC) (GLuint texture, GLint level, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, GLuint *params);\ntypedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLCREATEVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);\ntypedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index);\ntypedef void (APIENTRYP PFNGLENABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYELEMENTBUFFERPROC) (GLuint vaobj, GLuint buffer);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBUFFERPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBUFFERSPROC) (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBBINDINGPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBIFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBLFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYBINDINGDIVISORPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor);\ntypedef void (APIENTRYP PFNGLGETVERTEXARRAYIVPROC) (GLuint vaobj, GLenum pname, GLint *param);\ntypedef void (APIENTRYP PFNGLGETVERTEXARRAYINDEXEDIVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param);\ntypedef void (APIENTRYP PFNGLGETVERTEXARRAYINDEXED64IVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param);\ntypedef void (APIENTRYP PFNGLCREATESAMPLERSPROC) (GLsizei n, GLuint *samplers);\ntypedef void (APIENTRYP PFNGLCREATEPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines);\ntypedef void (APIENTRYP PFNGLCREATEQUERIESPROC) (GLenum target, GLsizei n, GLuint *ids);\ntypedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);\ntypedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);\ntypedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTUI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);\ntypedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTUIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);\ntypedef void (APIENTRYP PFNGLMEMORYBARRIERBYREGIONPROC) (GLbitfield barriers);\ntypedef void (APIENTRYP PFNGLGETTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels);\ntypedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels);\ntypedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSPROC) (void);\ntypedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLsizei bufSize, void *pixels);\ntypedef void (APIENTRYP PFNGLGETNTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMDVPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMFVPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMUIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params);\ntypedef void (APIENTRYP PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);\ntypedef void (APIENTRYP PFNGLTEXTUREBARRIERPROC) (void);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glClipControl (GLenum origin, GLenum depth);\nGLAPI void APIENTRY glCreateTransformFeedbacks (GLsizei n, GLuint *ids);\nGLAPI void APIENTRY glTransformFeedbackBufferBase (GLuint xfb, GLuint index, GLuint buffer);\nGLAPI void APIENTRY glTransformFeedbackBufferRange (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);\nGLAPI void APIENTRY glGetTransformFeedbackiv (GLuint xfb, GLenum pname, GLint *param);\nGLAPI void APIENTRY glGetTransformFeedbacki_v (GLuint xfb, GLenum pname, GLuint index, GLint *param);\nGLAPI void APIENTRY glGetTransformFeedbacki64_v (GLuint xfb, GLenum pname, GLuint index, GLint64 *param);\nGLAPI void APIENTRY glCreateBuffers (GLsizei n, GLuint *buffers);\nGLAPI void APIENTRY glNamedBufferStorage (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags);\nGLAPI void APIENTRY glNamedBufferData (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage);\nGLAPI void APIENTRY glNamedBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data);\nGLAPI void APIENTRY glCopyNamedBufferSubData (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);\nGLAPI void APIENTRY glClearNamedBufferData (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data);\nGLAPI void APIENTRY glClearNamedBufferSubData (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);\nGLAPI void *APIENTRY glMapNamedBuffer (GLuint buffer, GLenum access);\nGLAPI void *APIENTRY glMapNamedBufferRange (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);\nGLAPI GLboolean APIENTRY glUnmapNamedBuffer (GLuint buffer);\nGLAPI void APIENTRY glFlushMappedNamedBufferRange (GLuint buffer, GLintptr offset, GLsizeiptr length);\nGLAPI void APIENTRY glGetNamedBufferParameteriv (GLuint buffer, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetNamedBufferParameteri64v (GLuint buffer, GLenum pname, GLint64 *params);\nGLAPI void APIENTRY glGetNamedBufferPointerv (GLuint buffer, GLenum pname, void **params);\nGLAPI void APIENTRY glGetNamedBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data);\nGLAPI void APIENTRY glCreateFramebuffers (GLsizei n, GLuint *framebuffers);\nGLAPI void APIENTRY glNamedFramebufferRenderbuffer (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);\nGLAPI void APIENTRY glNamedFramebufferParameteri (GLuint framebuffer, GLenum pname, GLint param);\nGLAPI void APIENTRY glNamedFramebufferTexture (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);\nGLAPI void APIENTRY glNamedFramebufferTextureLayer (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);\nGLAPI void APIENTRY glNamedFramebufferDrawBuffer (GLuint framebuffer, GLenum buf);\nGLAPI void APIENTRY glNamedFramebufferDrawBuffers (GLuint framebuffer, GLsizei n, const GLenum *bufs);\nGLAPI void APIENTRY glNamedFramebufferReadBuffer (GLuint framebuffer, GLenum src);\nGLAPI void APIENTRY glInvalidateNamedFramebufferData (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments);\nGLAPI void APIENTRY glInvalidateNamedFramebufferSubData (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glClearNamedFramebufferiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value);\nGLAPI void APIENTRY glClearNamedFramebufferuiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value);\nGLAPI void APIENTRY glClearNamedFramebufferfv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value);\nGLAPI void APIENTRY glClearNamedFramebufferfi (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);\nGLAPI void APIENTRY glBlitNamedFramebuffer (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);\nGLAPI GLenum APIENTRY glCheckNamedFramebufferStatus (GLuint framebuffer, GLenum target);\nGLAPI void APIENTRY glGetNamedFramebufferParameteriv (GLuint framebuffer, GLenum pname, GLint *param);\nGLAPI void APIENTRY glGetNamedFramebufferAttachmentParameteriv (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params);\nGLAPI void APIENTRY glCreateRenderbuffers (GLsizei n, GLuint *renderbuffers);\nGLAPI void APIENTRY glNamedRenderbufferStorage (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glNamedRenderbufferStorageMultisample (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glGetNamedRenderbufferParameteriv (GLuint renderbuffer, GLenum pname, GLint *params);\nGLAPI void APIENTRY glCreateTextures (GLenum target, GLsizei n, GLuint *textures);\nGLAPI void APIENTRY glTextureBuffer (GLuint texture, GLenum internalformat, GLuint buffer);\nGLAPI void APIENTRY glTextureBufferRange (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);\nGLAPI void APIENTRY glTextureStorage1D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width);\nGLAPI void APIENTRY glTextureStorage2D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glTextureStorage3D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);\nGLAPI void APIENTRY glTextureStorage2DMultisample (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);\nGLAPI void APIENTRY glTextureStorage3DMultisample (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);\nGLAPI void APIENTRY glTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glCompressedTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glCompressedTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glCompressedTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);\nGLAPI void APIENTRY glCopyTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);\nGLAPI void APIENTRY glCopyTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glCopyTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glTextureParameterf (GLuint texture, GLenum pname, GLfloat param);\nGLAPI void APIENTRY glTextureParameterfv (GLuint texture, GLenum pname, const GLfloat *param);\nGLAPI void APIENTRY glTextureParameteri (GLuint texture, GLenum pname, GLint param);\nGLAPI void APIENTRY glTextureParameterIiv (GLuint texture, GLenum pname, const GLint *params);\nGLAPI void APIENTRY glTextureParameterIuiv (GLuint texture, GLenum pname, const GLuint *params);\nGLAPI void APIENTRY glTextureParameteriv (GLuint texture, GLenum pname, const GLint *param);\nGLAPI void APIENTRY glGenerateTextureMipmap (GLuint texture);\nGLAPI void APIENTRY glBindTextureUnit (GLuint unit, GLuint texture);\nGLAPI void APIENTRY glGetTextureImage (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels);\nGLAPI void APIENTRY glGetCompressedTextureImage (GLuint texture, GLint level, GLsizei bufSize, void *pixels);\nGLAPI void APIENTRY glGetTextureLevelParameterfv (GLuint texture, GLint level, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetTextureLevelParameteriv (GLuint texture, GLint level, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetTextureParameterfv (GLuint texture, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetTextureParameterIiv (GLuint texture, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetTextureParameterIuiv (GLuint texture, GLenum pname, GLuint *params);\nGLAPI void APIENTRY glGetTextureParameteriv (GLuint texture, GLenum pname, GLint *params);\nGLAPI void APIENTRY glCreateVertexArrays (GLsizei n, GLuint *arrays);\nGLAPI void APIENTRY glDisableVertexArrayAttrib (GLuint vaobj, GLuint index);\nGLAPI void APIENTRY glEnableVertexArrayAttrib (GLuint vaobj, GLuint index);\nGLAPI void APIENTRY glVertexArrayElementBuffer (GLuint vaobj, GLuint buffer);\nGLAPI void APIENTRY glVertexArrayVertexBuffer (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);\nGLAPI void APIENTRY glVertexArrayVertexBuffers (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides);\nGLAPI void APIENTRY glVertexArrayAttribBinding (GLuint vaobj, GLuint attribindex, GLuint bindingindex);\nGLAPI void APIENTRY glVertexArrayAttribFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);\nGLAPI void APIENTRY glVertexArrayAttribIFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\nGLAPI void APIENTRY glVertexArrayAttribLFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\nGLAPI void APIENTRY glVertexArrayBindingDivisor (GLuint vaobj, GLuint bindingindex, GLuint divisor);\nGLAPI void APIENTRY glGetVertexArrayiv (GLuint vaobj, GLenum pname, GLint *param);\nGLAPI void APIENTRY glGetVertexArrayIndexediv (GLuint vaobj, GLuint index, GLenum pname, GLint *param);\nGLAPI void APIENTRY glGetVertexArrayIndexed64iv (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param);\nGLAPI void APIENTRY glCreateSamplers (GLsizei n, GLuint *samplers);\nGLAPI void APIENTRY glCreateProgramPipelines (GLsizei n, GLuint *pipelines);\nGLAPI void APIENTRY glCreateQueries (GLenum target, GLsizei n, GLuint *ids);\nGLAPI void APIENTRY glGetQueryBufferObjecti64v (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);\nGLAPI void APIENTRY glGetQueryBufferObjectiv (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);\nGLAPI void APIENTRY glGetQueryBufferObjectui64v (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);\nGLAPI void APIENTRY glGetQueryBufferObjectuiv (GLuint id, GLuint buffer, GLenum pname, GLintptr offset);\nGLAPI void APIENTRY glMemoryBarrierByRegion (GLbitfield barriers);\nGLAPI void APIENTRY glGetTextureSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels);\nGLAPI void APIENTRY glGetCompressedTextureSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels);\nGLAPI GLenum APIENTRY glGetGraphicsResetStatus (void);\nGLAPI void APIENTRY glGetnCompressedTexImage (GLenum target, GLint lod, GLsizei bufSize, void *pixels);\nGLAPI void APIENTRY glGetnTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels);\nGLAPI void APIENTRY glGetnUniformdv (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);\nGLAPI void APIENTRY glGetnUniformfv (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);\nGLAPI void APIENTRY glGetnUniformiv (GLuint program, GLint location, GLsizei bufSize, GLint *params);\nGLAPI void APIENTRY glGetnUniformuiv (GLuint program, GLint location, GLsizei bufSize, GLuint *params);\nGLAPI void APIENTRY glReadnPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);\nGLAPI void APIENTRY glTextureBarrier (void);\n#endif\n#endif /* GL_VERSION_4_5 */\n\n#ifndef GL_VERSION_4_6\n#define GL_VERSION_4_6 1\n#define GL_SHADER_BINARY_FORMAT_SPIR_V    0x9551\n#define GL_SPIR_V_BINARY                  0x9552\n#define GL_PARAMETER_BUFFER               0x80EE\n#define GL_PARAMETER_BUFFER_BINDING       0x80EF\n#define GL_CONTEXT_FLAG_NO_ERROR_BIT      0x00000008\n#define GL_VERTICES_SUBMITTED             0x82EE\n#define GL_PRIMITIVES_SUBMITTED           0x82EF\n#define GL_VERTEX_SHADER_INVOCATIONS      0x82F0\n#define GL_TESS_CONTROL_SHADER_PATCHES    0x82F1\n#define GL_TESS_EVALUATION_SHADER_INVOCATIONS 0x82F2\n#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED 0x82F3\n#define GL_FRAGMENT_SHADER_INVOCATIONS    0x82F4\n#define GL_COMPUTE_SHADER_INVOCATIONS     0x82F5\n#define GL_CLIPPING_INPUT_PRIMITIVES      0x82F6\n#define GL_CLIPPING_OUTPUT_PRIMITIVES     0x82F7\n#define GL_POLYGON_OFFSET_CLAMP           0x8E1B\n#define GL_SPIR_V_EXTENSIONS              0x9553\n#define GL_NUM_SPIR_V_EXTENSIONS          0x9554\n#define GL_TEXTURE_MAX_ANISOTROPY         0x84FE\n#define GL_MAX_TEXTURE_MAX_ANISOTROPY     0x84FF\n#define GL_TRANSFORM_FEEDBACK_OVERFLOW    0x82EC\n#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW 0x82ED\ntypedef void (APIENTRYP PFNGLSPECIALIZESHADERPROC) (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue);\ntypedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC) (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);\ntypedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC) (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);\ntypedef void (APIENTRYP PFNGLPOLYGONOFFSETCLAMPPROC) (GLfloat factor, GLfloat units, GLfloat clamp);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glSpecializeShader (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue);\nGLAPI void APIENTRY glMultiDrawArraysIndirectCount (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);\nGLAPI void APIENTRY glMultiDrawElementsIndirectCount (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);\nGLAPI void APIENTRY glPolygonOffsetClamp (GLfloat factor, GLfloat units, GLfloat clamp);\n#endif\n#endif /* GL_VERSION_4_6 */\n\n#ifndef GL_ARB_ES2_compatibility\n#define GL_ARB_ES2_compatibility 1\n#endif /* GL_ARB_ES2_compatibility */\n\n#ifndef GL_ARB_ES3_1_compatibility\n#define GL_ARB_ES3_1_compatibility 1\n#endif /* GL_ARB_ES3_1_compatibility */\n\n#ifndef GL_ARB_ES3_2_compatibility\n#define GL_ARB_ES3_2_compatibility 1\n#define GL_PRIMITIVE_BOUNDING_BOX_ARB     0x92BE\n#define GL_MULTISAMPLE_LINE_WIDTH_RANGE_ARB 0x9381\n#define GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY_ARB 0x9382\ntypedef void (APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXARBPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glPrimitiveBoundingBoxARB (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);\n#endif\n#endif /* GL_ARB_ES3_2_compatibility */\n\n#ifndef GL_ARB_ES3_compatibility\n#define GL_ARB_ES3_compatibility 1\n#endif /* GL_ARB_ES3_compatibility */\n\n#ifndef GL_ARB_arrays_of_arrays\n#define GL_ARB_arrays_of_arrays 1\n#endif /* GL_ARB_arrays_of_arrays */\n\n#ifndef GL_ARB_base_instance\n#define GL_ARB_base_instance 1\n#endif /* GL_ARB_base_instance */\n\n#ifndef GL_ARB_bindless_texture\n#define GL_ARB_bindless_texture 1\ntypedef khronos_uint64_t GLuint64EXT;\n#define GL_UNSIGNED_INT64_ARB             0x140F\ntypedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLEARBPROC) (GLuint texture);\ntypedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLEARBPROC) (GLuint texture, GLuint sampler);\ntypedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle);\ntypedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC) (GLuint64 handle);\ntypedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLEARBPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);\ntypedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle, GLenum access);\ntypedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC) (GLuint64 handle);\ntypedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64ARBPROC) (GLint location, GLuint64 value);\ntypedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC) (GLuint program, GLint location, GLuint64 value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values);\ntypedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle);\ntypedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64ARBPROC) (GLuint index, GLuint64EXT x);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VARBPROC) (GLuint index, const GLuint64EXT *v);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VARBPROC) (GLuint index, GLenum pname, GLuint64EXT *params);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI GLuint64 APIENTRY glGetTextureHandleARB (GLuint texture);\nGLAPI GLuint64 APIENTRY glGetTextureSamplerHandleARB (GLuint texture, GLuint sampler);\nGLAPI void APIENTRY glMakeTextureHandleResidentARB (GLuint64 handle);\nGLAPI void APIENTRY glMakeTextureHandleNonResidentARB (GLuint64 handle);\nGLAPI GLuint64 APIENTRY glGetImageHandleARB (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);\nGLAPI void APIENTRY glMakeImageHandleResidentARB (GLuint64 handle, GLenum access);\nGLAPI void APIENTRY glMakeImageHandleNonResidentARB (GLuint64 handle);\nGLAPI void APIENTRY glUniformHandleui64ARB (GLint location, GLuint64 value);\nGLAPI void APIENTRY glUniformHandleui64vARB (GLint location, GLsizei count, const GLuint64 *value);\nGLAPI void APIENTRY glProgramUniformHandleui64ARB (GLuint program, GLint location, GLuint64 value);\nGLAPI void APIENTRY glProgramUniformHandleui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *values);\nGLAPI GLboolean APIENTRY glIsTextureHandleResidentARB (GLuint64 handle);\nGLAPI GLboolean APIENTRY glIsImageHandleResidentARB (GLuint64 handle);\nGLAPI void APIENTRY glVertexAttribL1ui64ARB (GLuint index, GLuint64EXT x);\nGLAPI void APIENTRY glVertexAttribL1ui64vARB (GLuint index, const GLuint64EXT *v);\nGLAPI void APIENTRY glGetVertexAttribLui64vARB (GLuint index, GLenum pname, GLuint64EXT *params);\n#endif\n#endif /* GL_ARB_bindless_texture */\n\n#ifndef GL_ARB_blend_func_extended\n#define GL_ARB_blend_func_extended 1\n#endif /* GL_ARB_blend_func_extended */\n\n#ifndef GL_ARB_buffer_storage\n#define GL_ARB_buffer_storage 1\n#endif /* GL_ARB_buffer_storage */\n\n#ifndef GL_ARB_cl_event\n#define GL_ARB_cl_event 1\nstruct _cl_context;\nstruct _cl_event;\n#define GL_SYNC_CL_EVENT_ARB              0x8240\n#define GL_SYNC_CL_EVENT_COMPLETE_ARB     0x8241\ntypedef GLsync (APIENTRYP PFNGLCREATESYNCFROMCLEVENTARBPROC) (struct _cl_context *context, struct _cl_event *event, GLbitfield flags);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context *context, struct _cl_event *event, GLbitfield flags);\n#endif\n#endif /* GL_ARB_cl_event */\n\n#ifndef GL_ARB_clear_buffer_object\n#define GL_ARB_clear_buffer_object 1\n#endif /* GL_ARB_clear_buffer_object */\n\n#ifndef GL_ARB_clear_texture\n#define GL_ARB_clear_texture 1\n#endif /* GL_ARB_clear_texture */\n\n#ifndef GL_ARB_clip_control\n#define GL_ARB_clip_control 1\n#endif /* GL_ARB_clip_control */\n\n#ifndef GL_ARB_compressed_texture_pixel_storage\n#define GL_ARB_compressed_texture_pixel_storage 1\n#endif /* GL_ARB_compressed_texture_pixel_storage */\n\n#ifndef GL_ARB_compute_shader\n#define GL_ARB_compute_shader 1\n#endif /* GL_ARB_compute_shader */\n\n#ifndef GL_ARB_compute_variable_group_size\n#define GL_ARB_compute_variable_group_size 1\n#define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344\n#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB\n#define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345\n#define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF\ntypedef void (APIENTRYP PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDispatchComputeGroupSizeARB (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z);\n#endif\n#endif /* GL_ARB_compute_variable_group_size */\n\n#ifndef GL_ARB_conditional_render_inverted\n#define GL_ARB_conditional_render_inverted 1\n#endif /* GL_ARB_conditional_render_inverted */\n\n#ifndef GL_ARB_conservative_depth\n#define GL_ARB_conservative_depth 1\n#endif /* GL_ARB_conservative_depth */\n\n#ifndef GL_ARB_copy_buffer\n#define GL_ARB_copy_buffer 1\n#endif /* GL_ARB_copy_buffer */\n\n#ifndef GL_ARB_copy_image\n#define GL_ARB_copy_image 1\n#endif /* GL_ARB_copy_image */\n\n#ifndef GL_ARB_cull_distance\n#define GL_ARB_cull_distance 1\n#endif /* GL_ARB_cull_distance */\n\n#ifndef GL_ARB_debug_output\n#define GL_ARB_debug_output 1\ntypedef void (APIENTRY  *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);\n#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB   0x8242\n#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243\n#define GL_DEBUG_CALLBACK_FUNCTION_ARB    0x8244\n#define GL_DEBUG_CALLBACK_USER_PARAM_ARB  0x8245\n#define GL_DEBUG_SOURCE_API_ARB           0x8246\n#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247\n#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248\n#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB   0x8249\n#define GL_DEBUG_SOURCE_APPLICATION_ARB   0x824A\n#define GL_DEBUG_SOURCE_OTHER_ARB         0x824B\n#define GL_DEBUG_TYPE_ERROR_ARB           0x824C\n#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D\n#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E\n#define GL_DEBUG_TYPE_PORTABILITY_ARB     0x824F\n#define GL_DEBUG_TYPE_PERFORMANCE_ARB     0x8250\n#define GL_DEBUG_TYPE_OTHER_ARB           0x8251\n#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB   0x9143\n#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB  0x9144\n#define GL_DEBUG_LOGGED_MESSAGES_ARB      0x9145\n#define GL_DEBUG_SEVERITY_HIGH_ARB        0x9146\n#define GL_DEBUG_SEVERITY_MEDIUM_ARB      0x9147\n#define GL_DEBUG_SEVERITY_LOW_ARB         0x9148\ntypedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);\ntypedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);\ntypedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const void *userParam);\ntypedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDebugMessageControlARB (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);\nGLAPI void APIENTRY glDebugMessageInsertARB (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);\nGLAPI void APIENTRY glDebugMessageCallbackARB (GLDEBUGPROCARB callback, const void *userParam);\nGLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);\n#endif\n#endif /* GL_ARB_debug_output */\n\n#ifndef GL_ARB_depth_buffer_float\n#define GL_ARB_depth_buffer_float 1\n#endif /* GL_ARB_depth_buffer_float */\n\n#ifndef GL_ARB_depth_clamp\n#define GL_ARB_depth_clamp 1\n#endif /* GL_ARB_depth_clamp */\n\n#ifndef GL_ARB_derivative_control\n#define GL_ARB_derivative_control 1\n#endif /* GL_ARB_derivative_control */\n\n#ifndef GL_ARB_direct_state_access\n#define GL_ARB_direct_state_access 1\n#endif /* GL_ARB_direct_state_access */\n\n#ifndef GL_ARB_draw_buffers_blend\n#define GL_ARB_draw_buffers_blend 1\ntypedef void (APIENTRYP PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode);\ntypedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);\ntypedef void (APIENTRYP PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst);\ntypedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBlendEquationiARB (GLuint buf, GLenum mode);\nGLAPI void APIENTRY glBlendEquationSeparateiARB (GLuint buf, GLenum modeRGB, GLenum modeAlpha);\nGLAPI void APIENTRY glBlendFunciARB (GLuint buf, GLenum src, GLenum dst);\nGLAPI void APIENTRY glBlendFuncSeparateiARB (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);\n#endif\n#endif /* GL_ARB_draw_buffers_blend */\n\n#ifndef GL_ARB_draw_elements_base_vertex\n#define GL_ARB_draw_elements_base_vertex 1\n#endif /* GL_ARB_draw_elements_base_vertex */\n\n#ifndef GL_ARB_draw_indirect\n#define GL_ARB_draw_indirect 1\n#endif /* GL_ARB_draw_indirect */\n\n#ifndef GL_ARB_draw_instanced\n#define GL_ARB_draw_instanced 1\ntypedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);\ntypedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count, GLsizei primcount);\nGLAPI void APIENTRY glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);\n#endif\n#endif /* GL_ARB_draw_instanced */\n\n#ifndef GL_ARB_enhanced_layouts\n#define GL_ARB_enhanced_layouts 1\n#endif /* GL_ARB_enhanced_layouts */\n\n#ifndef GL_ARB_explicit_attrib_location\n#define GL_ARB_explicit_attrib_location 1\n#endif /* GL_ARB_explicit_attrib_location */\n\n#ifndef GL_ARB_explicit_uniform_location\n#define GL_ARB_explicit_uniform_location 1\n#endif /* GL_ARB_explicit_uniform_location */\n\n#ifndef GL_ARB_fragment_coord_conventions\n#define GL_ARB_fragment_coord_conventions 1\n#endif /* GL_ARB_fragment_coord_conventions */\n\n#ifndef GL_ARB_fragment_layer_viewport\n#define GL_ARB_fragment_layer_viewport 1\n#endif /* GL_ARB_fragment_layer_viewport */\n\n#ifndef GL_ARB_fragment_shader_interlock\n#define GL_ARB_fragment_shader_interlock 1\n#endif /* GL_ARB_fragment_shader_interlock */\n\n#ifndef GL_ARB_framebuffer_no_attachments\n#define GL_ARB_framebuffer_no_attachments 1\n#endif /* GL_ARB_framebuffer_no_attachments */\n\n#ifndef GL_ARB_framebuffer_object\n#define GL_ARB_framebuffer_object 1\n#endif /* GL_ARB_framebuffer_object */\n\n#ifndef GL_ARB_framebuffer_sRGB\n#define GL_ARB_framebuffer_sRGB 1\n#endif /* GL_ARB_framebuffer_sRGB */\n\n#ifndef GL_ARB_geometry_shader4\n#define GL_ARB_geometry_shader4 1\n#define GL_LINES_ADJACENCY_ARB            0x000A\n#define GL_LINE_STRIP_ADJACENCY_ARB       0x000B\n#define GL_TRIANGLES_ADJACENCY_ARB        0x000C\n#define GL_TRIANGLE_STRIP_ADJACENCY_ARB   0x000D\n#define GL_PROGRAM_POINT_SIZE_ARB         0x8642\n#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29\n#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7\n#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8\n#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9\n#define GL_GEOMETRY_SHADER_ARB            0x8DD9\n#define GL_GEOMETRY_VERTICES_OUT_ARB      0x8DDA\n#define GL_GEOMETRY_INPUT_TYPE_ARB        0x8DDB\n#define GL_GEOMETRY_OUTPUT_TYPE_ARB       0x8DDC\n#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD\n#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE\n#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF\n#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0\n#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1\ntypedef void (APIENTRYP PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glProgramParameteriARB (GLuint program, GLenum pname, GLint value);\nGLAPI void APIENTRY glFramebufferTextureARB (GLenum target, GLenum attachment, GLuint texture, GLint level);\nGLAPI void APIENTRY glFramebufferTextureLayerARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);\nGLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);\n#endif\n#endif /* GL_ARB_geometry_shader4 */\n\n#ifndef GL_ARB_get_program_binary\n#define GL_ARB_get_program_binary 1\n#endif /* GL_ARB_get_program_binary */\n\n#ifndef GL_ARB_get_texture_sub_image\n#define GL_ARB_get_texture_sub_image 1\n#endif /* GL_ARB_get_texture_sub_image */\n\n#ifndef GL_ARB_gl_spirv\n#define GL_ARB_gl_spirv 1\n#define GL_SHADER_BINARY_FORMAT_SPIR_V_ARB 0x9551\n#define GL_SPIR_V_BINARY_ARB              0x9552\ntypedef void (APIENTRYP PFNGLSPECIALIZESHADERARBPROC) (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glSpecializeShaderARB (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue);\n#endif\n#endif /* GL_ARB_gl_spirv */\n\n#ifndef GL_ARB_gpu_shader5\n#define GL_ARB_gpu_shader5 1\n#endif /* GL_ARB_gpu_shader5 */\n\n#ifndef GL_ARB_gpu_shader_fp64\n#define GL_ARB_gpu_shader_fp64 1\n#endif /* GL_ARB_gpu_shader_fp64 */\n\n#ifndef GL_ARB_gpu_shader_int64\n#define GL_ARB_gpu_shader_int64 1\n#define GL_INT64_ARB                      0x140E\n#define GL_INT64_VEC2_ARB                 0x8FE9\n#define GL_INT64_VEC3_ARB                 0x8FEA\n#define GL_INT64_VEC4_ARB                 0x8FEB\n#define GL_UNSIGNED_INT64_VEC2_ARB        0x8FF5\n#define GL_UNSIGNED_INT64_VEC3_ARB        0x8FF6\n#define GL_UNSIGNED_INT64_VEC4_ARB        0x8FF7\ntypedef void (APIENTRYP PFNGLUNIFORM1I64ARBPROC) (GLint location, GLint64 x);\ntypedef void (APIENTRYP PFNGLUNIFORM2I64ARBPROC) (GLint location, GLint64 x, GLint64 y);\ntypedef void (APIENTRYP PFNGLUNIFORM3I64ARBPROC) (GLint location, GLint64 x, GLint64 y, GLint64 z);\ntypedef void (APIENTRYP PFNGLUNIFORM4I64ARBPROC) (GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w);\ntypedef void (APIENTRYP PFNGLUNIFORM1I64VARBPROC) (GLint location, GLsizei count, const GLint64 *value);\ntypedef void (APIENTRYP PFNGLUNIFORM2I64VARBPROC) (GLint location, GLsizei count, const GLint64 *value);\ntypedef void (APIENTRYP PFNGLUNIFORM3I64VARBPROC) (GLint location, GLsizei count, const GLint64 *value);\ntypedef void (APIENTRYP PFNGLUNIFORM4I64VARBPROC) (GLint location, GLsizei count, const GLint64 *value);\ntypedef void (APIENTRYP PFNGLUNIFORM1UI64ARBPROC) (GLint location, GLuint64 x);\ntypedef void (APIENTRYP PFNGLUNIFORM2UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y);\ntypedef void (APIENTRYP PFNGLUNIFORM3UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y, GLuint64 z);\ntypedef void (APIENTRYP PFNGLUNIFORM4UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w);\ntypedef void (APIENTRYP PFNGLUNIFORM1UI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value);\ntypedef void (APIENTRYP PFNGLUNIFORM2UI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value);\ntypedef void (APIENTRYP PFNGLUNIFORM3UI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value);\ntypedef void (APIENTRYP PFNGLUNIFORM4UI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value);\ntypedef void (APIENTRYP PFNGLGETUNIFORMI64VARBPROC) (GLuint program, GLint location, GLint64 *params);\ntypedef void (APIENTRYP PFNGLGETUNIFORMUI64VARBPROC) (GLuint program, GLint location, GLuint64 *params);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMI64VARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint64 *params);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMUI64VARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint64 *params);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64ARBPROC) (GLuint program, GLint location, GLint64 x);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64 *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64 *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64 *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64 *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64ARBPROC) (GLuint program, GLint location, GLuint64 x);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *value);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glUniform1i64ARB (GLint location, GLint64 x);\nGLAPI void APIENTRY glUniform2i64ARB (GLint location, GLint64 x, GLint64 y);\nGLAPI void APIENTRY glUniform3i64ARB (GLint location, GLint64 x, GLint64 y, GLint64 z);\nGLAPI void APIENTRY glUniform4i64ARB (GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w);\nGLAPI void APIENTRY glUniform1i64vARB (GLint location, GLsizei count, const GLint64 *value);\nGLAPI void APIENTRY glUniform2i64vARB (GLint location, GLsizei count, const GLint64 *value);\nGLAPI void APIENTRY glUniform3i64vARB (GLint location, GLsizei count, const GLint64 *value);\nGLAPI void APIENTRY glUniform4i64vARB (GLint location, GLsizei count, const GLint64 *value);\nGLAPI void APIENTRY glUniform1ui64ARB (GLint location, GLuint64 x);\nGLAPI void APIENTRY glUniform2ui64ARB (GLint location, GLuint64 x, GLuint64 y);\nGLAPI void APIENTRY glUniform3ui64ARB (GLint location, GLuint64 x, GLuint64 y, GLuint64 z);\nGLAPI void APIENTRY glUniform4ui64ARB (GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w);\nGLAPI void APIENTRY glUniform1ui64vARB (GLint location, GLsizei count, const GLuint64 *value);\nGLAPI void APIENTRY glUniform2ui64vARB (GLint location, GLsizei count, const GLuint64 *value);\nGLAPI void APIENTRY glUniform3ui64vARB (GLint location, GLsizei count, const GLuint64 *value);\nGLAPI void APIENTRY glUniform4ui64vARB (GLint location, GLsizei count, const GLuint64 *value);\nGLAPI void APIENTRY glGetUniformi64vARB (GLuint program, GLint location, GLint64 *params);\nGLAPI void APIENTRY glGetUniformui64vARB (GLuint program, GLint location, GLuint64 *params);\nGLAPI void APIENTRY glGetnUniformi64vARB (GLuint program, GLint location, GLsizei bufSize, GLint64 *params);\nGLAPI void APIENTRY glGetnUniformui64vARB (GLuint program, GLint location, GLsizei bufSize, GLuint64 *params);\nGLAPI void APIENTRY glProgramUniform1i64ARB (GLuint program, GLint location, GLint64 x);\nGLAPI void APIENTRY glProgramUniform2i64ARB (GLuint program, GLint location, GLint64 x, GLint64 y);\nGLAPI void APIENTRY glProgramUniform3i64ARB (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z);\nGLAPI void APIENTRY glProgramUniform4i64ARB (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w);\nGLAPI void APIENTRY glProgramUniform1i64vARB (GLuint program, GLint location, GLsizei count, const GLint64 *value);\nGLAPI void APIENTRY glProgramUniform2i64vARB (GLuint program, GLint location, GLsizei count, const GLint64 *value);\nGLAPI void APIENTRY glProgramUniform3i64vARB (GLuint program, GLint location, GLsizei count, const GLint64 *value);\nGLAPI void APIENTRY glProgramUniform4i64vARB (GLuint program, GLint location, GLsizei count, const GLint64 *value);\nGLAPI void APIENTRY glProgramUniform1ui64ARB (GLuint program, GLint location, GLuint64 x);\nGLAPI void APIENTRY glProgramUniform2ui64ARB (GLuint program, GLint location, GLuint64 x, GLuint64 y);\nGLAPI void APIENTRY glProgramUniform3ui64ARB (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z);\nGLAPI void APIENTRY glProgramUniform4ui64ARB (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w);\nGLAPI void APIENTRY glProgramUniform1ui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *value);\nGLAPI void APIENTRY glProgramUniform2ui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *value);\nGLAPI void APIENTRY glProgramUniform3ui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *value);\nGLAPI void APIENTRY glProgramUniform4ui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *value);\n#endif\n#endif /* GL_ARB_gpu_shader_int64 */\n\n#ifndef GL_ARB_half_float_vertex\n#define GL_ARB_half_float_vertex 1\n#endif /* GL_ARB_half_float_vertex */\n\n#ifndef GL_ARB_imaging\n#define GL_ARB_imaging 1\n#endif /* GL_ARB_imaging */\n\n#ifndef GL_ARB_indirect_parameters\n#define GL_ARB_indirect_parameters 1\n#define GL_PARAMETER_BUFFER_ARB           0x80EE\n#define GL_PARAMETER_BUFFER_BINDING_ARB   0x80EF\ntypedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);\ntypedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glMultiDrawArraysIndirectCountARB (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);\nGLAPI void APIENTRY glMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);\n#endif\n#endif /* GL_ARB_indirect_parameters */\n\n#ifndef GL_ARB_instanced_arrays\n#define GL_ARB_instanced_arrays 1\n#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glVertexAttribDivisorARB (GLuint index, GLuint divisor);\n#endif\n#endif /* GL_ARB_instanced_arrays */\n\n#ifndef GL_ARB_internalformat_query\n#define GL_ARB_internalformat_query 1\n#endif /* GL_ARB_internalformat_query */\n\n#ifndef GL_ARB_internalformat_query2\n#define GL_ARB_internalformat_query2 1\n#define GL_SRGB_DECODE_ARB                0x8299\n#define GL_VIEW_CLASS_EAC_R11             0x9383\n#define GL_VIEW_CLASS_EAC_RG11            0x9384\n#define GL_VIEW_CLASS_ETC2_RGB            0x9385\n#define GL_VIEW_CLASS_ETC2_RGBA           0x9386\n#define GL_VIEW_CLASS_ETC2_EAC_RGBA       0x9387\n#define GL_VIEW_CLASS_ASTC_4x4_RGBA       0x9388\n#define GL_VIEW_CLASS_ASTC_5x4_RGBA       0x9389\n#define GL_VIEW_CLASS_ASTC_5x5_RGBA       0x938A\n#define GL_VIEW_CLASS_ASTC_6x5_RGBA       0x938B\n#define GL_VIEW_CLASS_ASTC_6x6_RGBA       0x938C\n#define GL_VIEW_CLASS_ASTC_8x5_RGBA       0x938D\n#define GL_VIEW_CLASS_ASTC_8x6_RGBA       0x938E\n#define GL_VIEW_CLASS_ASTC_8x8_RGBA       0x938F\n#define GL_VIEW_CLASS_ASTC_10x5_RGBA      0x9390\n#define GL_VIEW_CLASS_ASTC_10x6_RGBA      0x9391\n#define GL_VIEW_CLASS_ASTC_10x8_RGBA      0x9392\n#define GL_VIEW_CLASS_ASTC_10x10_RGBA     0x9393\n#define GL_VIEW_CLASS_ASTC_12x10_RGBA     0x9394\n#define GL_VIEW_CLASS_ASTC_12x12_RGBA     0x9395\n#endif /* GL_ARB_internalformat_query2 */\n\n#ifndef GL_ARB_invalidate_subdata\n#define GL_ARB_invalidate_subdata 1\n#endif /* GL_ARB_invalidate_subdata */\n\n#ifndef GL_ARB_map_buffer_alignment\n#define GL_ARB_map_buffer_alignment 1\n#endif /* GL_ARB_map_buffer_alignment */\n\n#ifndef GL_ARB_map_buffer_range\n#define GL_ARB_map_buffer_range 1\n#endif /* GL_ARB_map_buffer_range */\n\n#ifndef GL_ARB_multi_bind\n#define GL_ARB_multi_bind 1\n#endif /* GL_ARB_multi_bind */\n\n#ifndef GL_ARB_multi_draw_indirect\n#define GL_ARB_multi_draw_indirect 1\n#endif /* GL_ARB_multi_draw_indirect */\n\n#ifndef GL_ARB_occlusion_query2\n#define GL_ARB_occlusion_query2 1\n#endif /* GL_ARB_occlusion_query2 */\n\n#ifndef GL_ARB_parallel_shader_compile\n#define GL_ARB_parallel_shader_compile 1\n#define GL_MAX_SHADER_COMPILER_THREADS_ARB 0x91B0\n#define GL_COMPLETION_STATUS_ARB          0x91B1\ntypedef void (APIENTRYP PFNGLMAXSHADERCOMPILERTHREADSARBPROC) (GLuint count);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glMaxShaderCompilerThreadsARB (GLuint count);\n#endif\n#endif /* GL_ARB_parallel_shader_compile */\n\n#ifndef GL_ARB_pipeline_statistics_query\n#define GL_ARB_pipeline_statistics_query 1\n#define GL_VERTICES_SUBMITTED_ARB         0x82EE\n#define GL_PRIMITIVES_SUBMITTED_ARB       0x82EF\n#define GL_VERTEX_SHADER_INVOCATIONS_ARB  0x82F0\n#define GL_TESS_CONTROL_SHADER_PATCHES_ARB 0x82F1\n#define GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB 0x82F2\n#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB 0x82F3\n#define GL_FRAGMENT_SHADER_INVOCATIONS_ARB 0x82F4\n#define GL_COMPUTE_SHADER_INVOCATIONS_ARB 0x82F5\n#define GL_CLIPPING_INPUT_PRIMITIVES_ARB  0x82F6\n#define GL_CLIPPING_OUTPUT_PRIMITIVES_ARB 0x82F7\n#endif /* GL_ARB_pipeline_statistics_query */\n\n#ifndef GL_ARB_pixel_buffer_object\n#define GL_ARB_pixel_buffer_object 1\n#define GL_PIXEL_PACK_BUFFER_ARB          0x88EB\n#define GL_PIXEL_UNPACK_BUFFER_ARB        0x88EC\n#define GL_PIXEL_PACK_BUFFER_BINDING_ARB  0x88ED\n#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF\n#endif /* GL_ARB_pixel_buffer_object */\n\n#ifndef GL_ARB_polygon_offset_clamp\n#define GL_ARB_polygon_offset_clamp 1\n#endif /* GL_ARB_polygon_offset_clamp */\n\n#ifndef GL_ARB_post_depth_coverage\n#define GL_ARB_post_depth_coverage 1\n#endif /* GL_ARB_post_depth_coverage */\n\n#ifndef GL_ARB_program_interface_query\n#define GL_ARB_program_interface_query 1\n#endif /* GL_ARB_program_interface_query */\n\n#ifndef GL_ARB_provoking_vertex\n#define GL_ARB_provoking_vertex 1\n#endif /* GL_ARB_provoking_vertex */\n\n#ifndef GL_ARB_query_buffer_object\n#define GL_ARB_query_buffer_object 1\n#endif /* GL_ARB_query_buffer_object */\n\n#ifndef GL_ARB_robust_buffer_access_behavior\n#define GL_ARB_robust_buffer_access_behavior 1\n#endif /* GL_ARB_robust_buffer_access_behavior */\n\n#ifndef GL_ARB_robustness\n#define GL_ARB_robustness 1\n#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004\n#define GL_LOSE_CONTEXT_ON_RESET_ARB      0x8252\n#define GL_GUILTY_CONTEXT_RESET_ARB       0x8253\n#define GL_INNOCENT_CONTEXT_RESET_ARB     0x8254\n#define GL_UNKNOWN_CONTEXT_RESET_ARB      0x8255\n#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256\n#define GL_NO_RESET_NOTIFICATION_ARB      0x8261\ntypedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void);\ntypedef void (APIENTRYP PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img);\ntypedef void (APIENTRYP PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);\ntypedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, void *img);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params);\ntypedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI GLenum APIENTRY glGetGraphicsResetStatusARB (void);\nGLAPI void APIENTRY glGetnTexImageARB (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *img);\nGLAPI void APIENTRY glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);\nGLAPI void APIENTRY glGetnCompressedTexImageARB (GLenum target, GLint lod, GLsizei bufSize, void *img);\nGLAPI void APIENTRY glGetnUniformfvARB (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);\nGLAPI void APIENTRY glGetnUniformivARB (GLuint program, GLint location, GLsizei bufSize, GLint *params);\nGLAPI void APIENTRY glGetnUniformuivARB (GLuint program, GLint location, GLsizei bufSize, GLuint *params);\nGLAPI void APIENTRY glGetnUniformdvARB (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);\n#endif\n#endif /* GL_ARB_robustness */\n\n#ifndef GL_ARB_robustness_isolation\n#define GL_ARB_robustness_isolation 1\n#endif /* GL_ARB_robustness_isolation */\n\n#ifndef GL_ARB_sample_locations\n#define GL_ARB_sample_locations 1\n#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_ARB 0x933D\n#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_ARB 0x933E\n#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_ARB 0x933F\n#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_ARB 0x9340\n#define GL_SAMPLE_LOCATION_ARB            0x8E50\n#define GL_PROGRAMMABLE_SAMPLE_LOCATION_ARB 0x9341\n#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB 0x9342\n#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB 0x9343\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLEVALUATEDEPTHVALUESARBPROC) (void);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glFramebufferSampleLocationsfvARB (GLenum target, GLuint start, GLsizei count, const GLfloat *v);\nGLAPI void APIENTRY glNamedFramebufferSampleLocationsfvARB (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v);\nGLAPI void APIENTRY glEvaluateDepthValuesARB (void);\n#endif\n#endif /* GL_ARB_sample_locations */\n\n#ifndef GL_ARB_sample_shading\n#define GL_ARB_sample_shading 1\n#define GL_SAMPLE_SHADING_ARB             0x8C36\n#define GL_MIN_SAMPLE_SHADING_VALUE_ARB   0x8C37\ntypedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLfloat value);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glMinSampleShadingARB (GLfloat value);\n#endif\n#endif /* GL_ARB_sample_shading */\n\n#ifndef GL_ARB_sampler_objects\n#define GL_ARB_sampler_objects 1\n#endif /* GL_ARB_sampler_objects */\n\n#ifndef GL_ARB_seamless_cube_map\n#define GL_ARB_seamless_cube_map 1\n#endif /* GL_ARB_seamless_cube_map */\n\n#ifndef GL_ARB_seamless_cubemap_per_texture\n#define GL_ARB_seamless_cubemap_per_texture 1\n#endif /* GL_ARB_seamless_cubemap_per_texture */\n\n#ifndef GL_ARB_separate_shader_objects\n#define GL_ARB_separate_shader_objects 1\n#endif /* GL_ARB_separate_shader_objects */\n\n#ifndef GL_ARB_shader_atomic_counter_ops\n#define GL_ARB_shader_atomic_counter_ops 1\n#endif /* GL_ARB_shader_atomic_counter_ops */\n\n#ifndef GL_ARB_shader_atomic_counters\n#define GL_ARB_shader_atomic_counters 1\n#endif /* GL_ARB_shader_atomic_counters */\n\n#ifndef GL_ARB_shader_ballot\n#define GL_ARB_shader_ballot 1\n#endif /* GL_ARB_shader_ballot */\n\n#ifndef GL_ARB_shader_bit_encoding\n#define GL_ARB_shader_bit_encoding 1\n#endif /* GL_ARB_shader_bit_encoding */\n\n#ifndef GL_ARB_shader_clock\n#define GL_ARB_shader_clock 1\n#endif /* GL_ARB_shader_clock */\n\n#ifndef GL_ARB_shader_draw_parameters\n#define GL_ARB_shader_draw_parameters 1\n#endif /* GL_ARB_shader_draw_parameters */\n\n#ifndef GL_ARB_shader_group_vote\n#define GL_ARB_shader_group_vote 1\n#endif /* GL_ARB_shader_group_vote */\n\n#ifndef GL_ARB_shader_image_load_store\n#define GL_ARB_shader_image_load_store 1\n#endif /* GL_ARB_shader_image_load_store */\n\n#ifndef GL_ARB_shader_image_size\n#define GL_ARB_shader_image_size 1\n#endif /* GL_ARB_shader_image_size */\n\n#ifndef GL_ARB_shader_precision\n#define GL_ARB_shader_precision 1\n#endif /* GL_ARB_shader_precision */\n\n#ifndef GL_ARB_shader_stencil_export\n#define GL_ARB_shader_stencil_export 1\n#endif /* GL_ARB_shader_stencil_export */\n\n#ifndef GL_ARB_shader_storage_buffer_object\n#define GL_ARB_shader_storage_buffer_object 1\n#endif /* GL_ARB_shader_storage_buffer_object */\n\n#ifndef GL_ARB_shader_subroutine\n#define GL_ARB_shader_subroutine 1\n#endif /* GL_ARB_shader_subroutine */\n\n#ifndef GL_ARB_shader_texture_image_samples\n#define GL_ARB_shader_texture_image_samples 1\n#endif /* GL_ARB_shader_texture_image_samples */\n\n#ifndef GL_ARB_shader_viewport_layer_array\n#define GL_ARB_shader_viewport_layer_array 1\n#endif /* GL_ARB_shader_viewport_layer_array */\n\n#ifndef GL_ARB_shading_language_420pack\n#define GL_ARB_shading_language_420pack 1\n#endif /* GL_ARB_shading_language_420pack */\n\n#ifndef GL_ARB_shading_language_include\n#define GL_ARB_shading_language_include 1\n#define GL_SHADER_INCLUDE_ARB             0x8DAE\n#define GL_NAMED_STRING_LENGTH_ARB        0x8DE9\n#define GL_NAMED_STRING_TYPE_ARB          0x8DEA\ntypedef void (APIENTRYP PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string);\ntypedef void (APIENTRYP PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name);\ntypedef void (APIENTRYP PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length);\ntypedef GLboolean (APIENTRYP PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name);\ntypedef void (APIENTRYP PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string);\ntypedef void (APIENTRYP PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar *name, GLenum pname, GLint *params);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glNamedStringARB (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string);\nGLAPI void APIENTRY glDeleteNamedStringARB (GLint namelen, const GLchar *name);\nGLAPI void APIENTRY glCompileShaderIncludeARB (GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length);\nGLAPI GLboolean APIENTRY glIsNamedStringARB (GLint namelen, const GLchar *name);\nGLAPI void APIENTRY glGetNamedStringARB (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string);\nGLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GLenum pname, GLint *params);\n#endif\n#endif /* GL_ARB_shading_language_include */\n\n#ifndef GL_ARB_shading_language_packing\n#define GL_ARB_shading_language_packing 1\n#endif /* GL_ARB_shading_language_packing */\n\n#ifndef GL_ARB_sparse_buffer\n#define GL_ARB_sparse_buffer 1\n#define GL_SPARSE_STORAGE_BIT_ARB         0x0400\n#define GL_SPARSE_BUFFER_PAGE_SIZE_ARB    0x82F8\ntypedef void (APIENTRYP PFNGLBUFFERPAGECOMMITMENTARBPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLboolean commit);\ntypedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit);\ntypedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBufferPageCommitmentARB (GLenum target, GLintptr offset, GLsizeiptr size, GLboolean commit);\nGLAPI void APIENTRY glNamedBufferPageCommitmentEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit);\nGLAPI void APIENTRY glNamedBufferPageCommitmentARB (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit);\n#endif\n#endif /* GL_ARB_sparse_buffer */\n\n#ifndef GL_ARB_sparse_texture\n#define GL_ARB_sparse_texture 1\n#define GL_TEXTURE_SPARSE_ARB             0x91A6\n#define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB    0x91A7\n#define GL_NUM_SPARSE_LEVELS_ARB          0x91AA\n#define GL_NUM_VIRTUAL_PAGE_SIZES_ARB     0x91A8\n#define GL_VIRTUAL_PAGE_SIZE_X_ARB        0x9195\n#define GL_VIRTUAL_PAGE_SIZE_Y_ARB        0x9196\n#define GL_VIRTUAL_PAGE_SIZE_Z_ARB        0x9197\n#define GL_MAX_SPARSE_TEXTURE_SIZE_ARB    0x9198\n#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199\n#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A\n#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9\ntypedef void (APIENTRYP PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glTexPageCommitmentARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);\n#endif\n#endif /* GL_ARB_sparse_texture */\n\n#ifndef GL_ARB_sparse_texture2\n#define GL_ARB_sparse_texture2 1\n#endif /* GL_ARB_sparse_texture2 */\n\n#ifndef GL_ARB_sparse_texture_clamp\n#define GL_ARB_sparse_texture_clamp 1\n#endif /* GL_ARB_sparse_texture_clamp */\n\n#ifndef GL_ARB_spirv_extensions\n#define GL_ARB_spirv_extensions 1\n#endif /* GL_ARB_spirv_extensions */\n\n#ifndef GL_ARB_stencil_texturing\n#define GL_ARB_stencil_texturing 1\n#endif /* GL_ARB_stencil_texturing */\n\n#ifndef GL_ARB_sync\n#define GL_ARB_sync 1\n#endif /* GL_ARB_sync */\n\n#ifndef GL_ARB_tessellation_shader\n#define GL_ARB_tessellation_shader 1\n#endif /* GL_ARB_tessellation_shader */\n\n#ifndef GL_ARB_texture_barrier\n#define GL_ARB_texture_barrier 1\n#endif /* GL_ARB_texture_barrier */\n\n#ifndef GL_ARB_texture_border_clamp\n#define GL_ARB_texture_border_clamp 1\n#define GL_CLAMP_TO_BORDER_ARB            0x812D\n#endif /* GL_ARB_texture_border_clamp */\n\n#ifndef GL_ARB_texture_buffer_object\n#define GL_ARB_texture_buffer_object 1\n#define GL_TEXTURE_BUFFER_ARB             0x8C2A\n#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB    0x8C2B\n#define GL_TEXTURE_BINDING_BUFFER_ARB     0x8C2C\n#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D\n#define GL_TEXTURE_BUFFER_FORMAT_ARB      0x8C2E\ntypedef void (APIENTRYP PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glTexBufferARB (GLenum target, GLenum internalformat, GLuint buffer);\n#endif\n#endif /* GL_ARB_texture_buffer_object */\n\n#ifndef GL_ARB_texture_buffer_object_rgb32\n#define GL_ARB_texture_buffer_object_rgb32 1\n#endif /* GL_ARB_texture_buffer_object_rgb32 */\n\n#ifndef GL_ARB_texture_buffer_range\n#define GL_ARB_texture_buffer_range 1\n#endif /* GL_ARB_texture_buffer_range */\n\n#ifndef GL_ARB_texture_compression_bptc\n#define GL_ARB_texture_compression_bptc 1\n#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C\n#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D\n#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E\n#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F\n#endif /* GL_ARB_texture_compression_bptc */\n\n#ifndef GL_ARB_texture_compression_rgtc\n#define GL_ARB_texture_compression_rgtc 1\n#endif /* GL_ARB_texture_compression_rgtc */\n\n#ifndef GL_ARB_texture_cube_map_array\n#define GL_ARB_texture_cube_map_array 1\n#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB     0x9009\n#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A\n#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B\n#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB     0x900C\n#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D\n#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E\n#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F\n#endif /* GL_ARB_texture_cube_map_array */\n\n#ifndef GL_ARB_texture_filter_anisotropic\n#define GL_ARB_texture_filter_anisotropic 1\n#endif /* GL_ARB_texture_filter_anisotropic */\n\n#ifndef GL_ARB_texture_filter_minmax\n#define GL_ARB_texture_filter_minmax 1\n#define GL_TEXTURE_REDUCTION_MODE_ARB     0x9366\n#define GL_WEIGHTED_AVERAGE_ARB           0x9367\n#endif /* GL_ARB_texture_filter_minmax */\n\n#ifndef GL_ARB_texture_gather\n#define GL_ARB_texture_gather 1\n#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E\n#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F\n#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F\n#endif /* GL_ARB_texture_gather */\n\n#ifndef GL_ARB_texture_mirror_clamp_to_edge\n#define GL_ARB_texture_mirror_clamp_to_edge 1\n#endif /* GL_ARB_texture_mirror_clamp_to_edge */\n\n#ifndef GL_ARB_texture_mirrored_repeat\n#define GL_ARB_texture_mirrored_repeat 1\n#define GL_MIRRORED_REPEAT_ARB            0x8370\n#endif /* GL_ARB_texture_mirrored_repeat */\n\n#ifndef GL_ARB_texture_multisample\n#define GL_ARB_texture_multisample 1\n#endif /* GL_ARB_texture_multisample */\n\n#ifndef GL_ARB_texture_non_power_of_two\n#define GL_ARB_texture_non_power_of_two 1\n#endif /* GL_ARB_texture_non_power_of_two */\n\n#ifndef GL_ARB_texture_query_levels\n#define GL_ARB_texture_query_levels 1\n#endif /* GL_ARB_texture_query_levels */\n\n#ifndef GL_ARB_texture_query_lod\n#define GL_ARB_texture_query_lod 1\n#endif /* GL_ARB_texture_query_lod */\n\n#ifndef GL_ARB_texture_rg\n#define GL_ARB_texture_rg 1\n#endif /* GL_ARB_texture_rg */\n\n#ifndef GL_ARB_texture_rgb10_a2ui\n#define GL_ARB_texture_rgb10_a2ui 1\n#endif /* GL_ARB_texture_rgb10_a2ui */\n\n#ifndef GL_ARB_texture_stencil8\n#define GL_ARB_texture_stencil8 1\n#endif /* GL_ARB_texture_stencil8 */\n\n#ifndef GL_ARB_texture_storage\n#define GL_ARB_texture_storage 1\n#endif /* GL_ARB_texture_storage */\n\n#ifndef GL_ARB_texture_storage_multisample\n#define GL_ARB_texture_storage_multisample 1\n#endif /* GL_ARB_texture_storage_multisample */\n\n#ifndef GL_ARB_texture_swizzle\n#define GL_ARB_texture_swizzle 1\n#endif /* GL_ARB_texture_swizzle */\n\n#ifndef GL_ARB_texture_view\n#define GL_ARB_texture_view 1\n#endif /* GL_ARB_texture_view */\n\n#ifndef GL_ARB_timer_query\n#define GL_ARB_timer_query 1\n#endif /* GL_ARB_timer_query */\n\n#ifndef GL_ARB_transform_feedback2\n#define GL_ARB_transform_feedback2 1\n#endif /* GL_ARB_transform_feedback2 */\n\n#ifndef GL_ARB_transform_feedback3\n#define GL_ARB_transform_feedback3 1\n#endif /* GL_ARB_transform_feedback3 */\n\n#ifndef GL_ARB_transform_feedback_instanced\n#define GL_ARB_transform_feedback_instanced 1\n#endif /* GL_ARB_transform_feedback_instanced */\n\n#ifndef GL_ARB_transform_feedback_overflow_query\n#define GL_ARB_transform_feedback_overflow_query 1\n#define GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB 0x82EC\n#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB 0x82ED\n#endif /* GL_ARB_transform_feedback_overflow_query */\n\n#ifndef GL_ARB_uniform_buffer_object\n#define GL_ARB_uniform_buffer_object 1\n#endif /* GL_ARB_uniform_buffer_object */\n\n#ifndef GL_ARB_vertex_array_bgra\n#define GL_ARB_vertex_array_bgra 1\n#endif /* GL_ARB_vertex_array_bgra */\n\n#ifndef GL_ARB_vertex_array_object\n#define GL_ARB_vertex_array_object 1\n#endif /* GL_ARB_vertex_array_object */\n\n#ifndef GL_ARB_vertex_attrib_64bit\n#define GL_ARB_vertex_attrib_64bit 1\n#endif /* GL_ARB_vertex_attrib_64bit */\n\n#ifndef GL_ARB_vertex_attrib_binding\n#define GL_ARB_vertex_attrib_binding 1\n#endif /* GL_ARB_vertex_attrib_binding */\n\n#ifndef GL_ARB_vertex_type_10f_11f_11f_rev\n#define GL_ARB_vertex_type_10f_11f_11f_rev 1\n#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */\n\n#ifndef GL_ARB_vertex_type_2_10_10_10_rev\n#define GL_ARB_vertex_type_2_10_10_10_rev 1\n#endif /* GL_ARB_vertex_type_2_10_10_10_rev */\n\n#ifndef GL_ARB_viewport_array\n#define GL_ARB_viewport_array 1\ntypedef void (APIENTRYP PFNGLDEPTHRANGEARRAYDVNVPROC) (GLuint first, GLsizei count, const GLdouble *v);\ntypedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDDNVPROC) (GLuint index, GLdouble n, GLdouble f);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDepthRangeArraydvNV (GLuint first, GLsizei count, const GLdouble *v);\nGLAPI void APIENTRY glDepthRangeIndexeddNV (GLuint index, GLdouble n, GLdouble f);\n#endif\n#endif /* GL_ARB_viewport_array */\n\n#ifndef GL_KHR_blend_equation_advanced\n#define GL_KHR_blend_equation_advanced 1\n#define GL_MULTIPLY_KHR                   0x9294\n#define GL_SCREEN_KHR                     0x9295\n#define GL_OVERLAY_KHR                    0x9296\n#define GL_DARKEN_KHR                     0x9297\n#define GL_LIGHTEN_KHR                    0x9298\n#define GL_COLORDODGE_KHR                 0x9299\n#define GL_COLORBURN_KHR                  0x929A\n#define GL_HARDLIGHT_KHR                  0x929B\n#define GL_SOFTLIGHT_KHR                  0x929C\n#define GL_DIFFERENCE_KHR                 0x929E\n#define GL_EXCLUSION_KHR                  0x92A0\n#define GL_HSL_HUE_KHR                    0x92AD\n#define GL_HSL_SATURATION_KHR             0x92AE\n#define GL_HSL_COLOR_KHR                  0x92AF\n#define GL_HSL_LUMINOSITY_KHR             0x92B0\ntypedef void (APIENTRYP PFNGLBLENDBARRIERKHRPROC) (void);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBlendBarrierKHR (void);\n#endif\n#endif /* GL_KHR_blend_equation_advanced */\n\n#ifndef GL_KHR_blend_equation_advanced_coherent\n#define GL_KHR_blend_equation_advanced_coherent 1\n#define GL_BLEND_ADVANCED_COHERENT_KHR    0x9285\n#endif /* GL_KHR_blend_equation_advanced_coherent */\n\n#ifndef GL_KHR_context_flush_control\n#define GL_KHR_context_flush_control 1\n#endif /* GL_KHR_context_flush_control */\n\n#ifndef GL_KHR_debug\n#define GL_KHR_debug 1\n#endif /* GL_KHR_debug */\n\n#ifndef GL_KHR_no_error\n#define GL_KHR_no_error 1\n#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR  0x00000008\n#endif /* GL_KHR_no_error */\n\n#ifndef GL_KHR_parallel_shader_compile\n#define GL_KHR_parallel_shader_compile 1\n#define GL_MAX_SHADER_COMPILER_THREADS_KHR 0x91B0\n#define GL_COMPLETION_STATUS_KHR          0x91B1\ntypedef void (APIENTRYP PFNGLMAXSHADERCOMPILERTHREADSKHRPROC) (GLuint count);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glMaxShaderCompilerThreadsKHR (GLuint count);\n#endif\n#endif /* GL_KHR_parallel_shader_compile */\n\n#ifndef GL_KHR_robust_buffer_access_behavior\n#define GL_KHR_robust_buffer_access_behavior 1\n#endif /* GL_KHR_robust_buffer_access_behavior */\n\n#ifndef GL_KHR_robustness\n#define GL_KHR_robustness 1\n#define GL_CONTEXT_ROBUST_ACCESS          0x90F3\n#endif /* GL_KHR_robustness */\n\n#ifndef GL_KHR_shader_subgroup\n#define GL_KHR_shader_subgroup 1\n#define GL_SUBGROUP_SIZE_KHR              0x9532\n#define GL_SUBGROUP_SUPPORTED_STAGES_KHR  0x9533\n#define GL_SUBGROUP_SUPPORTED_FEATURES_KHR 0x9534\n#define GL_SUBGROUP_QUAD_ALL_STAGES_KHR   0x9535\n#define GL_SUBGROUP_FEATURE_BASIC_BIT_KHR 0x00000001\n#define GL_SUBGROUP_FEATURE_VOTE_BIT_KHR  0x00000002\n#define GL_SUBGROUP_FEATURE_ARITHMETIC_BIT_KHR 0x00000004\n#define GL_SUBGROUP_FEATURE_BALLOT_BIT_KHR 0x00000008\n#define GL_SUBGROUP_FEATURE_SHUFFLE_BIT_KHR 0x00000010\n#define GL_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT_KHR 0x00000020\n#define GL_SUBGROUP_FEATURE_CLUSTERED_BIT_KHR 0x00000040\n#define GL_SUBGROUP_FEATURE_QUAD_BIT_KHR  0x00000080\n#endif /* GL_KHR_shader_subgroup */\n\n#ifndef GL_KHR_texture_compression_astc_hdr\n#define GL_KHR_texture_compression_astc_hdr 1\n#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR   0x93B0\n#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR   0x93B1\n#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR   0x93B2\n#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR   0x93B3\n#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR   0x93B4\n#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR   0x93B5\n#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR   0x93B6\n#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR   0x93B7\n#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR  0x93B8\n#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR  0x93B9\n#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR  0x93BA\n#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB\n#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC\n#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC\n#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD\n#endif /* GL_KHR_texture_compression_astc_hdr */\n\n#ifndef GL_KHR_texture_compression_astc_ldr\n#define GL_KHR_texture_compression_astc_ldr 1\n#endif /* GL_KHR_texture_compression_astc_ldr */\n\n#ifndef GL_KHR_texture_compression_astc_sliced_3d\n#define GL_KHR_texture_compression_astc_sliced_3d 1\n#endif /* GL_KHR_texture_compression_astc_sliced_3d */\n\n#ifndef GL_AMD_framebuffer_multisample_advanced\n#define GL_AMD_framebuffer_multisample_advanced 1\n#define GL_RENDERBUFFER_STORAGE_SAMPLES_AMD 0x91B2\n#define GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD 0x91B3\n#define GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD 0x91B4\n#define GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD 0x91B5\n#define GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B6\n#define GL_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B7\ntypedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glRenderbufferStorageMultisampleAdvancedAMD (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glNamedRenderbufferStorageMultisampleAdvancedAMD (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);\n#endif\n#endif /* GL_AMD_framebuffer_multisample_advanced */\n\n#ifndef GL_AMD_performance_monitor\n#define GL_AMD_performance_monitor 1\n#define GL_COUNTER_TYPE_AMD               0x8BC0\n#define GL_COUNTER_RANGE_AMD              0x8BC1\n#define GL_UNSIGNED_INT64_AMD             0x8BC2\n#define GL_PERCENTAGE_AMD                 0x8BC3\n#define GL_PERFMON_RESULT_AVAILABLE_AMD   0x8BC4\n#define GL_PERFMON_RESULT_SIZE_AMD        0x8BC5\n#define GL_PERFMON_RESULT_AMD             0x8BC6\ntypedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups);\ntypedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);\ntypedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);\ntypedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);\ntypedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data);\ntypedef void (APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);\ntypedef void (APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);\ntypedef void (APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList);\ntypedef void (APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor);\ntypedef void (APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor);\ntypedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups);\nGLAPI void APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);\nGLAPI void APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);\nGLAPI void APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);\nGLAPI void APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, void *data);\nGLAPI void APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors);\nGLAPI void APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors);\nGLAPI void APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList);\nGLAPI void APIENTRY glBeginPerfMonitorAMD (GLuint monitor);\nGLAPI void APIENTRY glEndPerfMonitorAMD (GLuint monitor);\nGLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);\n#endif\n#endif /* GL_AMD_performance_monitor */\n\n#ifndef GL_APPLE_rgb_422\n#define GL_APPLE_rgb_422 1\n#define GL_RGB_422_APPLE                  0x8A1F\n#define GL_UNSIGNED_SHORT_8_8_APPLE       0x85BA\n#define GL_UNSIGNED_SHORT_8_8_REV_APPLE   0x85BB\n#define GL_RGB_RAW_422_APPLE              0x8A51\n#endif /* GL_APPLE_rgb_422 */\n\n#ifndef GL_EXT_EGL_image_storage\n#define GL_EXT_EGL_image_storage 1\ntypedef void *GLeglImageOES;\ntypedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC) (GLenum target, GLeglImageOES image, const GLint* attrib_list);\ntypedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC) (GLuint texture, GLeglImageOES image, const GLint* attrib_list);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glEGLImageTargetTexStorageEXT (GLenum target, GLeglImageOES image, const GLint* attrib_list);\nGLAPI void APIENTRY glEGLImageTargetTextureStorageEXT (GLuint texture, GLeglImageOES image, const GLint* attrib_list);\n#endif\n#endif /* GL_EXT_EGL_image_storage */\n\n#ifndef GL_EXT_EGL_sync\n#define GL_EXT_EGL_sync 1\n#endif /* GL_EXT_EGL_sync */\n\n#ifndef GL_EXT_debug_label\n#define GL_EXT_debug_label 1\n#define GL_PROGRAM_PIPELINE_OBJECT_EXT    0x8A4F\n#define GL_PROGRAM_OBJECT_EXT             0x8B40\n#define GL_SHADER_OBJECT_EXT              0x8B48\n#define GL_BUFFER_OBJECT_EXT              0x9151\n#define GL_QUERY_OBJECT_EXT               0x9153\n#define GL_VERTEX_ARRAY_OBJECT_EXT        0x9154\ntypedef void (APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label);\ntypedef void (APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label);\nGLAPI void APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label);\n#endif\n#endif /* GL_EXT_debug_label */\n\n#ifndef GL_EXT_debug_marker\n#define GL_EXT_debug_marker 1\ntypedef void (APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker);\ntypedef void (APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker);\ntypedef void (APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker);\nGLAPI void APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker);\nGLAPI void APIENTRY glPopGroupMarkerEXT (void);\n#endif\n#endif /* GL_EXT_debug_marker */\n\n#ifndef GL_EXT_direct_state_access\n#define GL_EXT_direct_state_access 1\n#define GL_PROGRAM_MATRIX_EXT             0x8E2D\n#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT   0x8E2E\n#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F\ntypedef void (APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m);\ntypedef void (APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m);\ntypedef void (APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m);\ntypedef void (APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m);\ntypedef void (APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode);\ntypedef void (APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);\ntypedef void (APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);\ntypedef void (APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z);\ntypedef void (APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z);\ntypedef void (APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z);\ntypedef void (APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z);\ntypedef void (APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);\ntypedef void (APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);\ntypedef void (APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode);\ntypedef void (APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode);\ntypedef void (APIENTRYP PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask);\ntypedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat *params);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params);\ntypedef void (APIENTRYP PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);\ntypedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);\ntypedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);\ntypedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels);\ntypedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture);\ntypedef void (APIENTRYP PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer);\ntypedef void (APIENTRYP PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param);\ntypedef void (APIENTRYP PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);\ntypedef void (APIENTRYP PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params);\ntypedef void (APIENTRYP PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param);\ntypedef void (APIENTRYP PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params);\ntypedef void (APIENTRYP PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param);\ntypedef void (APIENTRYP PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params);\ntypedef void (APIENTRYP PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint *params);\ntypedef void (APIENTRYP PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params);\ntypedef void (APIENTRYP PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params);\ntypedef void (APIENTRYP PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param);\ntypedef void (APIENTRYP PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);\ntypedef void (APIENTRYP PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);\ntypedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);\ntypedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);\ntypedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels);\ntypedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);\ntypedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index);\ntypedef void (APIENTRYP PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index);\ntypedef void (APIENTRYP PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat *data);\ntypedef void (APIENTRYP PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble *data);\ntypedef void (APIENTRYP PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, void **data);\ntypedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index);\ntypedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index);\ntypedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index);\ntypedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data);\ntypedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits);\ntypedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint lod, void *img);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits);\ntypedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits);\ntypedef void (APIENTRYP PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint lod, void *img);\ntypedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m);\ntypedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m);\ntypedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m);\ntypedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m);\ntypedef void (APIENTRYP PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage);\ntypedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data);\ntypedef void *(APIENTRYP PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access);\ntypedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer);\ntypedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, void **params);\ntypedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer);\ntypedef void (APIENTRYP PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params);\ntypedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint *params);\ntypedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint *params);\ntypedef void (APIENTRYP PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params);\ntypedef void (APIENTRYP PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint *params);\ntypedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint *params);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);\ntypedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params);\ntypedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);\ntypedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint *params);\ntypedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params);\ntypedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);\ntypedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint *params);\ntypedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params);\ntypedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint *params);\ntypedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint *params);\ntypedef void (APIENTRYP PFNGLENABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index);\ntypedef void (APIENTRYP PFNGLDISABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index);\ntypedef void (APIENTRYP PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble *params);\ntypedef void (APIENTRYP PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, void **params);\ntypedef void (APIENTRYP PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const void *string);\ntypedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);\ntypedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble *params);\ntypedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);\ntypedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble *params);\ntypedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat *params);\ntypedef void (APIENTRYP PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, void *string);\ntypedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);\ntypedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target);\ntypedef void (APIENTRYP PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs);\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode);\ntypedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face);\ntypedef void (APIENTRYP PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer);\ntypedef void (APIENTRYP PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYINDEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYNORMALOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);\ntypedef void (APIENTRYP PFNGLENABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array);\ntypedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array);\ntypedef void (APIENTRYP PFNGLENABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index);\ntypedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index);\ntypedef void (APIENTRYP PFNGLGETVERTEXARRAYINTEGERVEXTPROC) (GLuint vaobj, GLenum pname, GLint *param);\ntypedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERVEXTPROC) (GLuint vaobj, GLenum pname, void **param);\ntypedef void (APIENTRYP PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param);\ntypedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, void **param);\ntypedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);\ntypedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);\ntypedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEEXTPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags);\ntypedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data);\ntypedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) (GLuint framebuffer, GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DEXTPROC) (GLuint program, GLint location, GLdouble x);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\ntypedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEEXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);\ntypedef void (APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);\ntypedef void (APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);\ntypedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);\ntypedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);\ntypedef void (APIENTRYP PFNGLTEXTUREPAGECOMMITMENTEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);\ntypedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC) (GLuint vaobj, GLuint index, GLuint divisor);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m);\nGLAPI void APIENTRY glMatrixLoaddEXT (GLenum mode, const GLdouble *m);\nGLAPI void APIENTRY glMatrixMultfEXT (GLenum mode, const GLfloat *m);\nGLAPI void APIENTRY glMatrixMultdEXT (GLenum mode, const GLdouble *m);\nGLAPI void APIENTRY glMatrixLoadIdentityEXT (GLenum mode);\nGLAPI void APIENTRY glMatrixRotatefEXT (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);\nGLAPI void APIENTRY glMatrixRotatedEXT (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);\nGLAPI void APIENTRY glMatrixScalefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z);\nGLAPI void APIENTRY glMatrixScaledEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z);\nGLAPI void APIENTRY glMatrixTranslatefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z);\nGLAPI void APIENTRY glMatrixTranslatedEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z);\nGLAPI void APIENTRY glMatrixFrustumEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);\nGLAPI void APIENTRY glMatrixOrthoEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);\nGLAPI void APIENTRY glMatrixPopEXT (GLenum mode);\nGLAPI void APIENTRY glMatrixPushEXT (GLenum mode);\nGLAPI void APIENTRY glClientAttribDefaultEXT (GLbitfield mask);\nGLAPI void APIENTRY glPushClientAttribDefaultEXT (GLbitfield mask);\nGLAPI void APIENTRY glTextureParameterfEXT (GLuint texture, GLenum target, GLenum pname, GLfloat param);\nGLAPI void APIENTRY glTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, const GLfloat *params);\nGLAPI void APIENTRY glTextureParameteriEXT (GLuint texture, GLenum target, GLenum pname, GLint param);\nGLAPI void APIENTRY glTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params);\nGLAPI void APIENTRY glTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glCopyTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);\nGLAPI void APIENTRY glCopyTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);\nGLAPI void APIENTRY glCopyTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);\nGLAPI void APIENTRY glCopyTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glGetTextureImageEXT (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels);\nGLAPI void APIENTRY glGetTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetTextureLevelParameterfvEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetTextureLevelParameterivEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params);\nGLAPI void APIENTRY glTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glCopyTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glBindMultiTextureEXT (GLenum texunit, GLenum target, GLuint texture);\nGLAPI void APIENTRY glMultiTexCoordPointerEXT (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer);\nGLAPI void APIENTRY glMultiTexEnvfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param);\nGLAPI void APIENTRY glMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);\nGLAPI void APIENTRY glMultiTexEnviEXT (GLenum texunit, GLenum target, GLenum pname, GLint param);\nGLAPI void APIENTRY glMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params);\nGLAPI void APIENTRY glMultiTexGendEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble param);\nGLAPI void APIENTRY glMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params);\nGLAPI void APIENTRY glMultiTexGenfEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat param);\nGLAPI void APIENTRY glMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params);\nGLAPI void APIENTRY glMultiTexGeniEXT (GLenum texunit, GLenum coord, GLenum pname, GLint param);\nGLAPI void APIENTRY glMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, const GLint *params);\nGLAPI void APIENTRY glGetMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params);\nGLAPI void APIENTRY glGetMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, GLint *params);\nGLAPI void APIENTRY glMultiTexParameteriEXT (GLenum texunit, GLenum target, GLenum pname, GLint param);\nGLAPI void APIENTRY glMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params);\nGLAPI void APIENTRY glMultiTexParameterfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param);\nGLAPI void APIENTRY glMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);\nGLAPI void APIENTRY glMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glCopyMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);\nGLAPI void APIENTRY glCopyMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);\nGLAPI void APIENTRY glCopyMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);\nGLAPI void APIENTRY glCopyMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glGetMultiTexImageEXT (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels);\nGLAPI void APIENTRY glGetMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetMultiTexLevelParameterfvEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params);\nGLAPI void APIENTRY glGetMultiTexLevelParameterivEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params);\nGLAPI void APIENTRY glMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);\nGLAPI void APIENTRY glCopyMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glEnableClientStateIndexedEXT (GLenum array, GLuint index);\nGLAPI void APIENTRY glDisableClientStateIndexedEXT (GLenum array, GLuint index);\nGLAPI void APIENTRY glGetFloatIndexedvEXT (GLenum target, GLuint index, GLfloat *data);\nGLAPI void APIENTRY glGetDoubleIndexedvEXT (GLenum target, GLuint index, GLdouble *data);\nGLAPI void APIENTRY glGetPointerIndexedvEXT (GLenum target, GLuint index, void **data);\nGLAPI void APIENTRY glEnableIndexedEXT (GLenum target, GLuint index);\nGLAPI void APIENTRY glDisableIndexedEXT (GLenum target, GLuint index);\nGLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum target, GLuint index);\nGLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum target, GLuint index, GLint *data);\nGLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum target, GLuint index, GLboolean *data);\nGLAPI void APIENTRY glCompressedTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits);\nGLAPI void APIENTRY glCompressedTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits);\nGLAPI void APIENTRY glCompressedTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits);\nGLAPI void APIENTRY glCompressedTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits);\nGLAPI void APIENTRY glCompressedTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits);\nGLAPI void APIENTRY glCompressedTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits);\nGLAPI void APIENTRY glGetCompressedTextureImageEXT (GLuint texture, GLenum target, GLint lod, void *img);\nGLAPI void APIENTRY glCompressedMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits);\nGLAPI void APIENTRY glCompressedMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits);\nGLAPI void APIENTRY glCompressedMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits);\nGLAPI void APIENTRY glCompressedMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits);\nGLAPI void APIENTRY glCompressedMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits);\nGLAPI void APIENTRY glCompressedMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits);\nGLAPI void APIENTRY glGetCompressedMultiTexImageEXT (GLenum texunit, GLenum target, GLint lod, void *img);\nGLAPI void APIENTRY glMatrixLoadTransposefEXT (GLenum mode, const GLfloat *m);\nGLAPI void APIENTRY glMatrixLoadTransposedEXT (GLenum mode, const GLdouble *m);\nGLAPI void APIENTRY glMatrixMultTransposefEXT (GLenum mode, const GLfloat *m);\nGLAPI void APIENTRY glMatrixMultTransposedEXT (GLenum mode, const GLdouble *m);\nGLAPI void APIENTRY glNamedBufferDataEXT (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage);\nGLAPI void APIENTRY glNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data);\nGLAPI void *APIENTRY glMapNamedBufferEXT (GLuint buffer, GLenum access);\nGLAPI GLboolean APIENTRY glUnmapNamedBufferEXT (GLuint buffer);\nGLAPI void APIENTRY glGetNamedBufferParameterivEXT (GLuint buffer, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetNamedBufferPointervEXT (GLuint buffer, GLenum pname, void **params);\nGLAPI void APIENTRY glGetNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data);\nGLAPI void APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0);\nGLAPI void APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1);\nGLAPI void APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);\nGLAPI void APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);\nGLAPI void APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0);\nGLAPI void APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1);\nGLAPI void APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);\nGLAPI void APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);\nGLAPI void APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);\nGLAPI void APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);\nGLAPI void APIENTRY glTextureBufferEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer);\nGLAPI void APIENTRY glMultiTexBufferEXT (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer);\nGLAPI void APIENTRY glTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params);\nGLAPI void APIENTRY glTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, const GLuint *params);\nGLAPI void APIENTRY glGetTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, GLuint *params);\nGLAPI void APIENTRY glMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params);\nGLAPI void APIENTRY glMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, const GLuint *params);\nGLAPI void APIENTRY glGetMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, GLuint *params);\nGLAPI void APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0);\nGLAPI void APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1);\nGLAPI void APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);\nGLAPI void APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);\nGLAPI void APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);\nGLAPI void APIENTRY glNamedProgramLocalParameters4fvEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params);\nGLAPI void APIENTRY glNamedProgramLocalParameterI4iEXT (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);\nGLAPI void APIENTRY glNamedProgramLocalParameterI4ivEXT (GLuint program, GLenum target, GLuint index, const GLint *params);\nGLAPI void APIENTRY glNamedProgramLocalParametersI4ivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params);\nGLAPI void APIENTRY glNamedProgramLocalParameterI4uiEXT (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);\nGLAPI void APIENTRY glNamedProgramLocalParameterI4uivEXT (GLuint program, GLenum target, GLuint index, const GLuint *params);\nGLAPI void APIENTRY glNamedProgramLocalParametersI4uivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params);\nGLAPI void APIENTRY glGetNamedProgramLocalParameterIivEXT (GLuint program, GLenum target, GLuint index, GLint *params);\nGLAPI void APIENTRY glGetNamedProgramLocalParameterIuivEXT (GLuint program, GLenum target, GLuint index, GLuint *params);\nGLAPI void APIENTRY glEnableClientStateiEXT (GLenum array, GLuint index);\nGLAPI void APIENTRY glDisableClientStateiEXT (GLenum array, GLuint index);\nGLAPI void APIENTRY glGetFloati_vEXT (GLenum pname, GLuint index, GLfloat *params);\nGLAPI void APIENTRY glGetDoublei_vEXT (GLenum pname, GLuint index, GLdouble *params);\nGLAPI void APIENTRY glGetPointeri_vEXT (GLenum pname, GLuint index, void **params);\nGLAPI void APIENTRY glNamedProgramStringEXT (GLuint program, GLenum target, GLenum format, GLsizei len, const void *string);\nGLAPI void APIENTRY glNamedProgramLocalParameter4dEXT (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);\nGLAPI void APIENTRY glNamedProgramLocalParameter4dvEXT (GLuint program, GLenum target, GLuint index, const GLdouble *params);\nGLAPI void APIENTRY glNamedProgramLocalParameter4fEXT (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);\nGLAPI void APIENTRY glNamedProgramLocalParameter4fvEXT (GLuint program, GLenum target, GLuint index, const GLfloat *params);\nGLAPI void APIENTRY glGetNamedProgramLocalParameterdvEXT (GLuint program, GLenum target, GLuint index, GLdouble *params);\nGLAPI void APIENTRY glGetNamedProgramLocalParameterfvEXT (GLuint program, GLenum target, GLuint index, GLfloat *params);\nGLAPI void APIENTRY glGetNamedProgramivEXT (GLuint program, GLenum target, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGetNamedProgramStringEXT (GLuint program, GLenum target, GLenum pname, void *string);\nGLAPI void APIENTRY glNamedRenderbufferStorageEXT (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glGetNamedRenderbufferParameterivEXT (GLuint renderbuffer, GLenum pname, GLint *params);\nGLAPI void APIENTRY glNamedRenderbufferStorageMultisampleEXT (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glNamedRenderbufferStorageMultisampleCoverageEXT (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI GLenum APIENTRY glCheckNamedFramebufferStatusEXT (GLuint framebuffer, GLenum target);\nGLAPI void APIENTRY glNamedFramebufferTexture1DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);\nGLAPI void APIENTRY glNamedFramebufferTexture2DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);\nGLAPI void APIENTRY glNamedFramebufferTexture3DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);\nGLAPI void APIENTRY glNamedFramebufferRenderbufferEXT (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);\nGLAPI void APIENTRY glGetNamedFramebufferAttachmentParameterivEXT (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params);\nGLAPI void APIENTRY glGenerateTextureMipmapEXT (GLuint texture, GLenum target);\nGLAPI void APIENTRY glGenerateMultiTexMipmapEXT (GLenum texunit, GLenum target);\nGLAPI void APIENTRY glFramebufferDrawBufferEXT (GLuint framebuffer, GLenum mode);\nGLAPI void APIENTRY glFramebufferDrawBuffersEXT (GLuint framebuffer, GLsizei n, const GLenum *bufs);\nGLAPI void APIENTRY glFramebufferReadBufferEXT (GLuint framebuffer, GLenum mode);\nGLAPI void APIENTRY glGetFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params);\nGLAPI void APIENTRY glNamedCopyBufferSubDataEXT (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);\nGLAPI void APIENTRY glNamedFramebufferTextureEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);\nGLAPI void APIENTRY glNamedFramebufferTextureLayerEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);\nGLAPI void APIENTRY glNamedFramebufferTextureFaceEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face);\nGLAPI void APIENTRY glTextureRenderbufferEXT (GLuint texture, GLenum target, GLuint renderbuffer);\nGLAPI void APIENTRY glMultiTexRenderbufferEXT (GLenum texunit, GLenum target, GLuint renderbuffer);\nGLAPI void APIENTRY glVertexArrayVertexOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);\nGLAPI void APIENTRY glVertexArrayColorOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);\nGLAPI void APIENTRY glVertexArrayEdgeFlagOffsetEXT (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset);\nGLAPI void APIENTRY glVertexArrayIndexOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);\nGLAPI void APIENTRY glVertexArrayNormalOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);\nGLAPI void APIENTRY glVertexArrayTexCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);\nGLAPI void APIENTRY glVertexArrayMultiTexCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset);\nGLAPI void APIENTRY glVertexArrayFogCoordOffsetEXT (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);\nGLAPI void APIENTRY glVertexArraySecondaryColorOffsetEXT (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);\nGLAPI void APIENTRY glVertexArrayVertexAttribOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset);\nGLAPI void APIENTRY glVertexArrayVertexAttribIOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);\nGLAPI void APIENTRY glEnableVertexArrayEXT (GLuint vaobj, GLenum array);\nGLAPI void APIENTRY glDisableVertexArrayEXT (GLuint vaobj, GLenum array);\nGLAPI void APIENTRY glEnableVertexArrayAttribEXT (GLuint vaobj, GLuint index);\nGLAPI void APIENTRY glDisableVertexArrayAttribEXT (GLuint vaobj, GLuint index);\nGLAPI void APIENTRY glGetVertexArrayIntegervEXT (GLuint vaobj, GLenum pname, GLint *param);\nGLAPI void APIENTRY glGetVertexArrayPointervEXT (GLuint vaobj, GLenum pname, void **param);\nGLAPI void APIENTRY glGetVertexArrayIntegeri_vEXT (GLuint vaobj, GLuint index, GLenum pname, GLint *param);\nGLAPI void APIENTRY glGetVertexArrayPointeri_vEXT (GLuint vaobj, GLuint index, GLenum pname, void **param);\nGLAPI void *APIENTRY glMapNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);\nGLAPI void APIENTRY glFlushMappedNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length);\nGLAPI void APIENTRY glNamedBufferStorageEXT (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags);\nGLAPI void APIENTRY glClearNamedBufferDataEXT (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data);\nGLAPI void APIENTRY glClearNamedBufferSubDataEXT (GLuint buffer, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);\nGLAPI void APIENTRY glNamedFramebufferParameteriEXT (GLuint framebuffer, GLenum pname, GLint param);\nGLAPI void APIENTRY glGetNamedFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params);\nGLAPI void APIENTRY glProgramUniform1dEXT (GLuint program, GLint location, GLdouble x);\nGLAPI void APIENTRY glProgramUniform2dEXT (GLuint program, GLint location, GLdouble x, GLdouble y);\nGLAPI void APIENTRY glProgramUniform3dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z);\nGLAPI void APIENTRY glProgramUniform4dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);\nGLAPI void APIENTRY glProgramUniform1dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniform2dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniform3dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniform4dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix2x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix2x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix3x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix3x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix4x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glProgramUniformMatrix4x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);\nGLAPI void APIENTRY glTextureBufferRangeEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);\nGLAPI void APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);\nGLAPI void APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);\nGLAPI void APIENTRY glTextureStorage2DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);\nGLAPI void APIENTRY glTextureStorage3DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);\nGLAPI void APIENTRY glVertexArrayBindVertexBufferEXT (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);\nGLAPI void APIENTRY glVertexArrayVertexAttribFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);\nGLAPI void APIENTRY glVertexArrayVertexAttribIFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\nGLAPI void APIENTRY glVertexArrayVertexAttribLFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);\nGLAPI void APIENTRY glVertexArrayVertexAttribBindingEXT (GLuint vaobj, GLuint attribindex, GLuint bindingindex);\nGLAPI void APIENTRY glVertexArrayVertexBindingDivisorEXT (GLuint vaobj, GLuint bindingindex, GLuint divisor);\nGLAPI void APIENTRY glVertexArrayVertexAttribLOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);\nGLAPI void APIENTRY glTexturePageCommitmentEXT (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);\nGLAPI void APIENTRY glVertexArrayVertexAttribDivisorEXT (GLuint vaobj, GLuint index, GLuint divisor);\n#endif\n#endif /* GL_EXT_direct_state_access */\n\n#ifndef GL_EXT_draw_instanced\n#define GL_EXT_draw_instanced 1\ntypedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);\ntypedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount);\nGLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);\n#endif\n#endif /* GL_EXT_draw_instanced */\n\n#ifndef GL_EXT_multiview_tessellation_geometry_shader\n#define GL_EXT_multiview_tessellation_geometry_shader 1\n#endif /* GL_EXT_multiview_tessellation_geometry_shader */\n\n#ifndef GL_EXT_multiview_texture_multisample\n#define GL_EXT_multiview_texture_multisample 1\n#endif /* GL_EXT_multiview_texture_multisample */\n\n#ifndef GL_EXT_multiview_timer_query\n#define GL_EXT_multiview_timer_query 1\n#endif /* GL_EXT_multiview_timer_query */\n\n#ifndef GL_EXT_polygon_offset_clamp\n#define GL_EXT_polygon_offset_clamp 1\n#define GL_POLYGON_OFFSET_CLAMP_EXT       0x8E1B\ntypedef void (APIENTRYP PFNGLPOLYGONOFFSETCLAMPEXTPROC) (GLfloat factor, GLfloat units, GLfloat clamp);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glPolygonOffsetClampEXT (GLfloat factor, GLfloat units, GLfloat clamp);\n#endif\n#endif /* GL_EXT_polygon_offset_clamp */\n\n#ifndef GL_EXT_post_depth_coverage\n#define GL_EXT_post_depth_coverage 1\n#endif /* GL_EXT_post_depth_coverage */\n\n#ifndef GL_EXT_raster_multisample\n#define GL_EXT_raster_multisample 1\n#define GL_RASTER_MULTISAMPLE_EXT         0x9327\n#define GL_RASTER_SAMPLES_EXT             0x9328\n#define GL_MAX_RASTER_SAMPLES_EXT         0x9329\n#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A\n#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B\n#define GL_EFFECTIVE_RASTER_SAMPLES_EXT   0x932C\ntypedef void (APIENTRYP PFNGLRASTERSAMPLESEXTPROC) (GLuint samples, GLboolean fixedsamplelocations);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glRasterSamplesEXT (GLuint samples, GLboolean fixedsamplelocations);\n#endif\n#endif /* GL_EXT_raster_multisample */\n\n#ifndef GL_EXT_separate_shader_objects\n#define GL_EXT_separate_shader_objects 1\n#define GL_ACTIVE_PROGRAM_EXT             0x8B8D\ntypedef void (APIENTRYP PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program);\ntypedef void (APIENTRYP PFNGLACTIVEPROGRAMEXTPROC) (GLuint program);\ntypedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar *string);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glUseShaderProgramEXT (GLenum type, GLuint program);\nGLAPI void APIENTRY glActiveProgramEXT (GLuint program);\nGLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum type, const GLchar *string);\n#endif\n#endif /* GL_EXT_separate_shader_objects */\n\n#ifndef GL_EXT_shader_framebuffer_fetch\n#define GL_EXT_shader_framebuffer_fetch 1\n#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52\n#endif /* GL_EXT_shader_framebuffer_fetch */\n\n#ifndef GL_EXT_shader_framebuffer_fetch_non_coherent\n#define GL_EXT_shader_framebuffer_fetch_non_coherent 1\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC) (void);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glFramebufferFetchBarrierEXT (void);\n#endif\n#endif /* GL_EXT_shader_framebuffer_fetch_non_coherent */\n\n#ifndef GL_EXT_shader_integer_mix\n#define GL_EXT_shader_integer_mix 1\n#endif /* GL_EXT_shader_integer_mix */\n\n#ifndef GL_EXT_texture_compression_s3tc\n#define GL_EXT_texture_compression_s3tc 1\n#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT   0x83F0\n#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT  0x83F1\n#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT  0x83F2\n#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT  0x83F3\n#endif /* GL_EXT_texture_compression_s3tc */\n\n#ifndef GL_EXT_texture_filter_minmax\n#define GL_EXT_texture_filter_minmax 1\n#define GL_TEXTURE_REDUCTION_MODE_EXT     0x9366\n#define GL_WEIGHTED_AVERAGE_EXT           0x9367\n#endif /* GL_EXT_texture_filter_minmax */\n\n#ifndef GL_EXT_texture_sRGB_R8\n#define GL_EXT_texture_sRGB_R8 1\n#define GL_SR8_EXT                        0x8FBD\n#endif /* GL_EXT_texture_sRGB_R8 */\n\n#ifndef GL_EXT_texture_sRGB_RG8\n#define GL_EXT_texture_sRGB_RG8 1\n#define GL_SRG8_EXT                       0x8FBE\n#endif /* GL_EXT_texture_sRGB_RG8 */\n\n#ifndef GL_EXT_texture_sRGB_decode\n#define GL_EXT_texture_sRGB_decode 1\n#define GL_TEXTURE_SRGB_DECODE_EXT        0x8A48\n#define GL_DECODE_EXT                     0x8A49\n#define GL_SKIP_DECODE_EXT                0x8A4A\n#endif /* GL_EXT_texture_sRGB_decode */\n\n#ifndef GL_EXT_texture_shadow_lod\n#define GL_EXT_texture_shadow_lod 1\n#endif /* GL_EXT_texture_shadow_lod */\n\n#ifndef GL_EXT_texture_storage\n#define GL_EXT_texture_storage 1\n#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT   0x912F\n#define GL_ALPHA8_EXT                     0x803C\n#define GL_LUMINANCE8_EXT                 0x8040\n#define GL_LUMINANCE8_ALPHA8_EXT          0x8045\n#define GL_RGBA32F_EXT                    0x8814\n#define GL_RGB32F_EXT                     0x8815\n#define GL_ALPHA32F_EXT                   0x8816\n#define GL_LUMINANCE32F_EXT               0x8818\n#define GL_LUMINANCE_ALPHA32F_EXT         0x8819\n#define GL_RGBA16F_EXT                    0x881A\n#define GL_RGB16F_EXT                     0x881B\n#define GL_ALPHA16F_EXT                   0x881C\n#define GL_LUMINANCE16F_EXT               0x881E\n#define GL_LUMINANCE_ALPHA16F_EXT         0x881F\n#define GL_RGB10_A2_EXT                   0x8059\n#define GL_RGB10_EXT                      0x8052\n#define GL_BGRA8_EXT                      0x93A1\n#define GL_R8_EXT                         0x8229\n#define GL_RG8_EXT                        0x822B\n#define GL_R32F_EXT                       0x822E\n#define GL_RG32F_EXT                      0x8230\n#define GL_R16F_EXT                       0x822D\n#define GL_RG16F_EXT                      0x822F\ntypedef void (APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);\ntypedef void (APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);\nGLAPI void APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glTexStorage3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);\n#endif\n#endif /* GL_EXT_texture_storage */\n\n#ifndef GL_EXT_window_rectangles\n#define GL_EXT_window_rectangles 1\n#define GL_INCLUSIVE_EXT                  0x8F10\n#define GL_EXCLUSIVE_EXT                  0x8F11\n#define GL_WINDOW_RECTANGLE_EXT           0x8F12\n#define GL_WINDOW_RECTANGLE_MODE_EXT      0x8F13\n#define GL_MAX_WINDOW_RECTANGLES_EXT      0x8F14\n#define GL_NUM_WINDOW_RECTANGLES_EXT      0x8F15\ntypedef void (APIENTRYP PFNGLWINDOWRECTANGLESEXTPROC) (GLenum mode, GLsizei count, const GLint *box);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glWindowRectanglesEXT (GLenum mode, GLsizei count, const GLint *box);\n#endif\n#endif /* GL_EXT_window_rectangles */\n\n#ifndef GL_INTEL_blackhole_render\n#define GL_INTEL_blackhole_render 1\n#define GL_BLACKHOLE_RENDER_INTEL         0x83FC\n#endif /* GL_INTEL_blackhole_render */\n\n#ifndef GL_INTEL_conservative_rasterization\n#define GL_INTEL_conservative_rasterization 1\n#define GL_CONSERVATIVE_RASTERIZATION_INTEL 0x83FE\n#endif /* GL_INTEL_conservative_rasterization */\n\n#ifndef GL_INTEL_framebuffer_CMAA\n#define GL_INTEL_framebuffer_CMAA 1\ntypedef void (APIENTRYP PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC) (void);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glApplyFramebufferAttachmentCMAAINTEL (void);\n#endif\n#endif /* GL_INTEL_framebuffer_CMAA */\n\n#ifndef GL_INTEL_performance_query\n#define GL_INTEL_performance_query 1\n#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000\n#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x00000001\n#define GL_PERFQUERY_WAIT_INTEL           0x83FB\n#define GL_PERFQUERY_FLUSH_INTEL          0x83FA\n#define GL_PERFQUERY_DONOT_FLUSH_INTEL    0x83F9\n#define GL_PERFQUERY_COUNTER_EVENT_INTEL  0x94F0\n#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1\n#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2\n#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3\n#define GL_PERFQUERY_COUNTER_RAW_INTEL    0x94F4\n#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5\n#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8\n#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9\n#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA\n#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB\n#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC\n#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD\n#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE\n#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF\n#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500\ntypedef void (APIENTRYP PFNGLBEGINPERFQUERYINTELPROC) (GLuint queryHandle);\ntypedef void (APIENTRYP PFNGLCREATEPERFQUERYINTELPROC) (GLuint queryId, GLuint *queryHandle);\ntypedef void (APIENTRYP PFNGLDELETEPERFQUERYINTELPROC) (GLuint queryHandle);\ntypedef void (APIENTRYP PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle);\ntypedef void (APIENTRYP PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint *queryId);\ntypedef void (APIENTRYP PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint *nextQueryId);\ntypedef void (APIENTRYP PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue);\ntypedef void (APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten);\ntypedef void (APIENTRYP PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar *queryName, GLuint *queryId);\ntypedef void (APIENTRYP PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBeginPerfQueryINTEL (GLuint queryHandle);\nGLAPI void APIENTRY glCreatePerfQueryINTEL (GLuint queryId, GLuint *queryHandle);\nGLAPI void APIENTRY glDeletePerfQueryINTEL (GLuint queryHandle);\nGLAPI void APIENTRY glEndPerfQueryINTEL (GLuint queryHandle);\nGLAPI void APIENTRY glGetFirstPerfQueryIdINTEL (GLuint *queryId);\nGLAPI void APIENTRY glGetNextPerfQueryIdINTEL (GLuint queryId, GLuint *nextQueryId);\nGLAPI void APIENTRY glGetPerfCounterInfoINTEL (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue);\nGLAPI void APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten);\nGLAPI void APIENTRY glGetPerfQueryIdByNameINTEL (GLchar *queryName, GLuint *queryId);\nGLAPI void APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask);\n#endif\n#endif /* GL_INTEL_performance_query */\n\n#ifndef GL_MESA_framebuffer_flip_x\n#define GL_MESA_framebuffer_flip_x 1\n#define GL_FRAMEBUFFER_FLIP_X_MESA        0x8BBC\n#endif /* GL_MESA_framebuffer_flip_x */\n\n#ifndef GL_MESA_framebuffer_flip_y\n#define GL_MESA_framebuffer_flip_y 1\n#define GL_FRAMEBUFFER_FLIP_Y_MESA        0x8BBB\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIMESAPROC) (GLenum target, GLenum pname, GLint param);\ntypedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVMESAPROC) (GLenum target, GLenum pname, GLint *params);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glFramebufferParameteriMESA (GLenum target, GLenum pname, GLint param);\nGLAPI void APIENTRY glGetFramebufferParameterivMESA (GLenum target, GLenum pname, GLint *params);\n#endif\n#endif /* GL_MESA_framebuffer_flip_y */\n\n#ifndef GL_MESA_framebuffer_swap_xy\n#define GL_MESA_framebuffer_swap_xy 1\n#define GL_FRAMEBUFFER_SWAP_XY_MESA       0x8BBD\n#endif /* GL_MESA_framebuffer_swap_xy */\n\n#ifndef GL_NV_bindless_multi_draw_indirect\n#define GL_NV_bindless_multi_draw_indirect 1\ntypedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount);\ntypedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glMultiDrawArraysIndirectBindlessNV (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount);\nGLAPI void APIENTRY glMultiDrawElementsIndirectBindlessNV (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount);\n#endif\n#endif /* GL_NV_bindless_multi_draw_indirect */\n\n#ifndef GL_NV_bindless_multi_draw_indirect_count\n#define GL_NV_bindless_multi_draw_indirect_count 1\ntypedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount);\ntypedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glMultiDrawArraysIndirectBindlessCountNV (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount);\nGLAPI void APIENTRY glMultiDrawElementsIndirectBindlessCountNV (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount);\n#endif\n#endif /* GL_NV_bindless_multi_draw_indirect_count */\n\n#ifndef GL_NV_bindless_texture\n#define GL_NV_bindless_texture 1\ntypedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture);\ntypedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler);\ntypedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle);\ntypedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle);\ntypedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);\ntypedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access);\ntypedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle);\ntypedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value);\ntypedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64 *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values);\ntypedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle);\ntypedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI GLuint64 APIENTRY glGetTextureHandleNV (GLuint texture);\nGLAPI GLuint64 APIENTRY glGetTextureSamplerHandleNV (GLuint texture, GLuint sampler);\nGLAPI void APIENTRY glMakeTextureHandleResidentNV (GLuint64 handle);\nGLAPI void APIENTRY glMakeTextureHandleNonResidentNV (GLuint64 handle);\nGLAPI GLuint64 APIENTRY glGetImageHandleNV (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);\nGLAPI void APIENTRY glMakeImageHandleResidentNV (GLuint64 handle, GLenum access);\nGLAPI void APIENTRY glMakeImageHandleNonResidentNV (GLuint64 handle);\nGLAPI void APIENTRY glUniformHandleui64NV (GLint location, GLuint64 value);\nGLAPI void APIENTRY glUniformHandleui64vNV (GLint location, GLsizei count, const GLuint64 *value);\nGLAPI void APIENTRY glProgramUniformHandleui64NV (GLuint program, GLint location, GLuint64 value);\nGLAPI void APIENTRY glProgramUniformHandleui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64 *values);\nGLAPI GLboolean APIENTRY glIsTextureHandleResidentNV (GLuint64 handle);\nGLAPI GLboolean APIENTRY glIsImageHandleResidentNV (GLuint64 handle);\n#endif\n#endif /* GL_NV_bindless_texture */\n\n#ifndef GL_NV_blend_equation_advanced\n#define GL_NV_blend_equation_advanced 1\n#define GL_BLEND_OVERLAP_NV               0x9281\n#define GL_BLEND_PREMULTIPLIED_SRC_NV     0x9280\n#define GL_BLUE_NV                        0x1905\n#define GL_COLORBURN_NV                   0x929A\n#define GL_COLORDODGE_NV                  0x9299\n#define GL_CONJOINT_NV                    0x9284\n#define GL_CONTRAST_NV                    0x92A1\n#define GL_DARKEN_NV                      0x9297\n#define GL_DIFFERENCE_NV                  0x929E\n#define GL_DISJOINT_NV                    0x9283\n#define GL_DST_ATOP_NV                    0x928F\n#define GL_DST_IN_NV                      0x928B\n#define GL_DST_NV                         0x9287\n#define GL_DST_OUT_NV                     0x928D\n#define GL_DST_OVER_NV                    0x9289\n#define GL_EXCLUSION_NV                   0x92A0\n#define GL_GREEN_NV                       0x1904\n#define GL_HARDLIGHT_NV                   0x929B\n#define GL_HARDMIX_NV                     0x92A9\n#define GL_HSL_COLOR_NV                   0x92AF\n#define GL_HSL_HUE_NV                     0x92AD\n#define GL_HSL_LUMINOSITY_NV              0x92B0\n#define GL_HSL_SATURATION_NV              0x92AE\n#define GL_INVERT_OVG_NV                  0x92B4\n#define GL_INVERT_RGB_NV                  0x92A3\n#define GL_LIGHTEN_NV                     0x9298\n#define GL_LINEARBURN_NV                  0x92A5\n#define GL_LINEARDODGE_NV                 0x92A4\n#define GL_LINEARLIGHT_NV                 0x92A7\n#define GL_MINUS_CLAMPED_NV               0x92B3\n#define GL_MINUS_NV                       0x929F\n#define GL_MULTIPLY_NV                    0x9294\n#define GL_OVERLAY_NV                     0x9296\n#define GL_PINLIGHT_NV                    0x92A8\n#define GL_PLUS_CLAMPED_ALPHA_NV          0x92B2\n#define GL_PLUS_CLAMPED_NV                0x92B1\n#define GL_PLUS_DARKER_NV                 0x9292\n#define GL_PLUS_NV                        0x9291\n#define GL_RED_NV                         0x1903\n#define GL_SCREEN_NV                      0x9295\n#define GL_SOFTLIGHT_NV                   0x929C\n#define GL_SRC_ATOP_NV                    0x928E\n#define GL_SRC_IN_NV                      0x928A\n#define GL_SRC_NV                         0x9286\n#define GL_SRC_OUT_NV                     0x928C\n#define GL_SRC_OVER_NV                    0x9288\n#define GL_UNCORRELATED_NV                0x9282\n#define GL_VIVIDLIGHT_NV                  0x92A6\n#define GL_XOR_NV                         0x1506\ntypedef void (APIENTRYP PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint value);\ntypedef void (APIENTRYP PFNGLBLENDBARRIERNVPROC) (void);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBlendParameteriNV (GLenum pname, GLint value);\nGLAPI void APIENTRY glBlendBarrierNV (void);\n#endif\n#endif /* GL_NV_blend_equation_advanced */\n\n#ifndef GL_NV_blend_equation_advanced_coherent\n#define GL_NV_blend_equation_advanced_coherent 1\n#define GL_BLEND_ADVANCED_COHERENT_NV     0x9285\n#endif /* GL_NV_blend_equation_advanced_coherent */\n\n#ifndef GL_NV_blend_minmax_factor\n#define GL_NV_blend_minmax_factor 1\n#define GL_FACTOR_MIN_AMD                 0x901C\n#define GL_FACTOR_MAX_AMD                 0x901D\n#endif /* GL_NV_blend_minmax_factor */\n\n#ifndef GL_NV_clip_space_w_scaling\n#define GL_NV_clip_space_w_scaling 1\n#define GL_VIEWPORT_POSITION_W_SCALE_NV   0x937C\n#define GL_VIEWPORT_POSITION_W_SCALE_X_COEFF_NV 0x937D\n#define GL_VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV 0x937E\ntypedef void (APIENTRYP PFNGLVIEWPORTPOSITIONWSCALENVPROC) (GLuint index, GLfloat xcoeff, GLfloat ycoeff);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glViewportPositionWScaleNV (GLuint index, GLfloat xcoeff, GLfloat ycoeff);\n#endif\n#endif /* GL_NV_clip_space_w_scaling */\n\n#ifndef GL_NV_command_list\n#define GL_NV_command_list 1\n#define GL_TERMINATE_SEQUENCE_COMMAND_NV  0x0000\n#define GL_NOP_COMMAND_NV                 0x0001\n#define GL_DRAW_ELEMENTS_COMMAND_NV       0x0002\n#define GL_DRAW_ARRAYS_COMMAND_NV         0x0003\n#define GL_DRAW_ELEMENTS_STRIP_COMMAND_NV 0x0004\n#define GL_DRAW_ARRAYS_STRIP_COMMAND_NV   0x0005\n#define GL_DRAW_ELEMENTS_INSTANCED_COMMAND_NV 0x0006\n#define GL_DRAW_ARRAYS_INSTANCED_COMMAND_NV 0x0007\n#define GL_ELEMENT_ADDRESS_COMMAND_NV     0x0008\n#define GL_ATTRIBUTE_ADDRESS_COMMAND_NV   0x0009\n#define GL_UNIFORM_ADDRESS_COMMAND_NV     0x000A\n#define GL_BLEND_COLOR_COMMAND_NV         0x000B\n#define GL_STENCIL_REF_COMMAND_NV         0x000C\n#define GL_LINE_WIDTH_COMMAND_NV          0x000D\n#define GL_POLYGON_OFFSET_COMMAND_NV      0x000E\n#define GL_ALPHA_REF_COMMAND_NV           0x000F\n#define GL_VIEWPORT_COMMAND_NV            0x0010\n#define GL_SCISSOR_COMMAND_NV             0x0011\n#define GL_FRONT_FACE_COMMAND_NV          0x0012\ntypedef void (APIENTRYP PFNGLCREATESTATESNVPROC) (GLsizei n, GLuint *states);\ntypedef void (APIENTRYP PFNGLDELETESTATESNVPROC) (GLsizei n, const GLuint *states);\ntypedef GLboolean (APIENTRYP PFNGLISSTATENVPROC) (GLuint state);\ntypedef void (APIENTRYP PFNGLSTATECAPTURENVPROC) (GLuint state, GLenum mode);\ntypedef GLuint (APIENTRYP PFNGLGETCOMMANDHEADERNVPROC) (GLenum tokenID, GLuint size);\ntypedef GLushort (APIENTRYP PFNGLGETSTAGEINDEXNVPROC) (GLenum shadertype);\ntypedef void (APIENTRYP PFNGLDRAWCOMMANDSNVPROC) (GLenum primitiveMode, GLuint buffer, const GLintptr *indirects, const GLsizei *sizes, GLuint count);\ntypedef void (APIENTRYP PFNGLDRAWCOMMANDSADDRESSNVPROC) (GLenum primitiveMode, const GLuint64 *indirects, const GLsizei *sizes, GLuint count);\ntypedef void (APIENTRYP PFNGLDRAWCOMMANDSSTATESNVPROC) (GLuint buffer, const GLintptr *indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count);\ntypedef void (APIENTRYP PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC) (const GLuint64 *indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count);\ntypedef void (APIENTRYP PFNGLCREATECOMMANDLISTSNVPROC) (GLsizei n, GLuint *lists);\ntypedef void (APIENTRYP PFNGLDELETECOMMANDLISTSNVPROC) (GLsizei n, const GLuint *lists);\ntypedef GLboolean (APIENTRYP PFNGLISCOMMANDLISTNVPROC) (GLuint list);\ntypedef void (APIENTRYP PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC) (GLuint list, GLuint segment, const void **indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count);\ntypedef void (APIENTRYP PFNGLCOMMANDLISTSEGMENTSNVPROC) (GLuint list, GLuint segments);\ntypedef void (APIENTRYP PFNGLCOMPILECOMMANDLISTNVPROC) (GLuint list);\ntypedef void (APIENTRYP PFNGLCALLCOMMANDLISTNVPROC) (GLuint list);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glCreateStatesNV (GLsizei n, GLuint *states);\nGLAPI void APIENTRY glDeleteStatesNV (GLsizei n, const GLuint *states);\nGLAPI GLboolean APIENTRY glIsStateNV (GLuint state);\nGLAPI void APIENTRY glStateCaptureNV (GLuint state, GLenum mode);\nGLAPI GLuint APIENTRY glGetCommandHeaderNV (GLenum tokenID, GLuint size);\nGLAPI GLushort APIENTRY glGetStageIndexNV (GLenum shadertype);\nGLAPI void APIENTRY glDrawCommandsNV (GLenum primitiveMode, GLuint buffer, const GLintptr *indirects, const GLsizei *sizes, GLuint count);\nGLAPI void APIENTRY glDrawCommandsAddressNV (GLenum primitiveMode, const GLuint64 *indirects, const GLsizei *sizes, GLuint count);\nGLAPI void APIENTRY glDrawCommandsStatesNV (GLuint buffer, const GLintptr *indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count);\nGLAPI void APIENTRY glDrawCommandsStatesAddressNV (const GLuint64 *indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count);\nGLAPI void APIENTRY glCreateCommandListsNV (GLsizei n, GLuint *lists);\nGLAPI void APIENTRY glDeleteCommandListsNV (GLsizei n, const GLuint *lists);\nGLAPI GLboolean APIENTRY glIsCommandListNV (GLuint list);\nGLAPI void APIENTRY glListDrawCommandsStatesClientNV (GLuint list, GLuint segment, const void **indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count);\nGLAPI void APIENTRY glCommandListSegmentsNV (GLuint list, GLuint segments);\nGLAPI void APIENTRY glCompileCommandListNV (GLuint list);\nGLAPI void APIENTRY glCallCommandListNV (GLuint list);\n#endif\n#endif /* GL_NV_command_list */\n\n#ifndef GL_NV_compute_shader_derivatives\n#define GL_NV_compute_shader_derivatives 1\n#endif /* GL_NV_compute_shader_derivatives */\n\n#ifndef GL_NV_conditional_render\n#define GL_NV_conditional_render 1\n#define GL_QUERY_WAIT_NV                  0x8E13\n#define GL_QUERY_NO_WAIT_NV               0x8E14\n#define GL_QUERY_BY_REGION_WAIT_NV        0x8E15\n#define GL_QUERY_BY_REGION_NO_WAIT_NV     0x8E16\ntypedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode);\ntypedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode);\nGLAPI void APIENTRY glEndConditionalRenderNV (void);\n#endif\n#endif /* GL_NV_conditional_render */\n\n#ifndef GL_NV_conservative_raster\n#define GL_NV_conservative_raster 1\n#define GL_CONSERVATIVE_RASTERIZATION_NV  0x9346\n#define GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV 0x9347\n#define GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV 0x9348\n#define GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV 0x9349\ntypedef void (APIENTRYP PFNGLSUBPIXELPRECISIONBIASNVPROC) (GLuint xbits, GLuint ybits);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glSubpixelPrecisionBiasNV (GLuint xbits, GLuint ybits);\n#endif\n#endif /* GL_NV_conservative_raster */\n\n#ifndef GL_NV_conservative_raster_dilate\n#define GL_NV_conservative_raster_dilate 1\n#define GL_CONSERVATIVE_RASTER_DILATE_NV  0x9379\n#define GL_CONSERVATIVE_RASTER_DILATE_RANGE_NV 0x937A\n#define GL_CONSERVATIVE_RASTER_DILATE_GRANULARITY_NV 0x937B\ntypedef void (APIENTRYP PFNGLCONSERVATIVERASTERPARAMETERFNVPROC) (GLenum pname, GLfloat value);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glConservativeRasterParameterfNV (GLenum pname, GLfloat value);\n#endif\n#endif /* GL_NV_conservative_raster_dilate */\n\n#ifndef GL_NV_conservative_raster_pre_snap\n#define GL_NV_conservative_raster_pre_snap 1\n#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_NV 0x9550\n#endif /* GL_NV_conservative_raster_pre_snap */\n\n#ifndef GL_NV_conservative_raster_pre_snap_triangles\n#define GL_NV_conservative_raster_pre_snap_triangles 1\n#define GL_CONSERVATIVE_RASTER_MODE_NV    0x954D\n#define GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV 0x954E\n#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV 0x954F\ntypedef void (APIENTRYP PFNGLCONSERVATIVERASTERPARAMETERINVPROC) (GLenum pname, GLint param);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glConservativeRasterParameteriNV (GLenum pname, GLint param);\n#endif\n#endif /* GL_NV_conservative_raster_pre_snap_triangles */\n\n#ifndef GL_NV_conservative_raster_underestimation\n#define GL_NV_conservative_raster_underestimation 1\n#endif /* GL_NV_conservative_raster_underestimation */\n\n#ifndef GL_NV_depth_buffer_float\n#define GL_NV_depth_buffer_float 1\n#define GL_DEPTH_COMPONENT32F_NV          0x8DAB\n#define GL_DEPTH32F_STENCIL8_NV           0x8DAC\n#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD\n#define GL_DEPTH_BUFFER_FLOAT_MODE_NV     0x8DAF\ntypedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar);\ntypedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth);\ntypedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDepthRangedNV (GLdouble zNear, GLdouble zFar);\nGLAPI void APIENTRY glClearDepthdNV (GLdouble depth);\nGLAPI void APIENTRY glDepthBoundsdNV (GLdouble zmin, GLdouble zmax);\n#endif\n#endif /* GL_NV_depth_buffer_float */\n\n#ifndef GL_NV_draw_vulkan_image\n#define GL_NV_draw_vulkan_image 1\ntypedef void (APIENTRY  *GLVULKANPROCNV)(void);\ntypedef void (APIENTRYP PFNGLDRAWVKIMAGENVPROC) (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1);\ntypedef GLVULKANPROCNV (APIENTRYP PFNGLGETVKPROCADDRNVPROC) (const GLchar *name);\ntypedef void (APIENTRYP PFNGLWAITVKSEMAPHORENVPROC) (GLuint64 vkSemaphore);\ntypedef void (APIENTRYP PFNGLSIGNALVKSEMAPHORENVPROC) (GLuint64 vkSemaphore);\ntypedef void (APIENTRYP PFNGLSIGNALVKFENCENVPROC) (GLuint64 vkFence);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDrawVkImageNV (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1);\nGLAPI GLVULKANPROCNV APIENTRY glGetVkProcAddrNV (const GLchar *name);\nGLAPI void APIENTRY glWaitVkSemaphoreNV (GLuint64 vkSemaphore);\nGLAPI void APIENTRY glSignalVkSemaphoreNV (GLuint64 vkSemaphore);\nGLAPI void APIENTRY glSignalVkFenceNV (GLuint64 vkFence);\n#endif\n#endif /* GL_NV_draw_vulkan_image */\n\n#ifndef GL_NV_fill_rectangle\n#define GL_NV_fill_rectangle 1\n#define GL_FILL_RECTANGLE_NV              0x933C\n#endif /* GL_NV_fill_rectangle */\n\n#ifndef GL_NV_fragment_coverage_to_color\n#define GL_NV_fragment_coverage_to_color 1\n#define GL_FRAGMENT_COVERAGE_TO_COLOR_NV  0x92DD\n#define GL_FRAGMENT_COVERAGE_COLOR_NV     0x92DE\ntypedef void (APIENTRYP PFNGLFRAGMENTCOVERAGECOLORNVPROC) (GLuint color);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glFragmentCoverageColorNV (GLuint color);\n#endif\n#endif /* GL_NV_fragment_coverage_to_color */\n\n#ifndef GL_NV_fragment_shader_barycentric\n#define GL_NV_fragment_shader_barycentric 1\n#endif /* GL_NV_fragment_shader_barycentric */\n\n#ifndef GL_NV_fragment_shader_interlock\n#define GL_NV_fragment_shader_interlock 1\n#endif /* GL_NV_fragment_shader_interlock */\n\n#ifndef GL_NV_framebuffer_mixed_samples\n#define GL_NV_framebuffer_mixed_samples 1\n#define GL_COVERAGE_MODULATION_TABLE_NV   0x9331\n#define GL_COLOR_SAMPLES_NV               0x8E20\n#define GL_DEPTH_SAMPLES_NV               0x932D\n#define GL_STENCIL_SAMPLES_NV             0x932E\n#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F\n#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330\n#define GL_COVERAGE_MODULATION_NV         0x9332\n#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333\ntypedef void (APIENTRYP PFNGLCOVERAGEMODULATIONTABLENVPROC) (GLsizei n, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLGETCOVERAGEMODULATIONTABLENVPROC) (GLsizei bufSize, GLfloat *v);\ntypedef void (APIENTRYP PFNGLCOVERAGEMODULATIONNVPROC) (GLenum components);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glCoverageModulationTableNV (GLsizei n, const GLfloat *v);\nGLAPI void APIENTRY glGetCoverageModulationTableNV (GLsizei bufSize, GLfloat *v);\nGLAPI void APIENTRY glCoverageModulationNV (GLenum components);\n#endif\n#endif /* GL_NV_framebuffer_mixed_samples */\n\n#ifndef GL_NV_framebuffer_multisample_coverage\n#define GL_NV_framebuffer_multisample_coverage 1\n#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB\n#define GL_RENDERBUFFER_COLOR_SAMPLES_NV  0x8E10\n#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11\n#define GL_MULTISAMPLE_COVERAGE_MODES_NV  0x8E12\ntypedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);\n#endif\n#endif /* GL_NV_framebuffer_multisample_coverage */\n\n#ifndef GL_NV_geometry_shader_passthrough\n#define GL_NV_geometry_shader_passthrough 1\n#endif /* GL_NV_geometry_shader_passthrough */\n\n#ifndef GL_NV_gpu_shader5\n#define GL_NV_gpu_shader5 1\ntypedef khronos_int64_t GLint64EXT;\n#define GL_INT64_NV                       0x140E\n#define GL_UNSIGNED_INT64_NV              0x140F\n#define GL_INT8_NV                        0x8FE0\n#define GL_INT8_VEC2_NV                   0x8FE1\n#define GL_INT8_VEC3_NV                   0x8FE2\n#define GL_INT8_VEC4_NV                   0x8FE3\n#define GL_INT16_NV                       0x8FE4\n#define GL_INT16_VEC2_NV                  0x8FE5\n#define GL_INT16_VEC3_NV                  0x8FE6\n#define GL_INT16_VEC4_NV                  0x8FE7\n#define GL_INT64_VEC2_NV                  0x8FE9\n#define GL_INT64_VEC3_NV                  0x8FEA\n#define GL_INT64_VEC4_NV                  0x8FEB\n#define GL_UNSIGNED_INT8_NV               0x8FEC\n#define GL_UNSIGNED_INT8_VEC2_NV          0x8FED\n#define GL_UNSIGNED_INT8_VEC3_NV          0x8FEE\n#define GL_UNSIGNED_INT8_VEC4_NV          0x8FEF\n#define GL_UNSIGNED_INT16_NV              0x8FF0\n#define GL_UNSIGNED_INT16_VEC2_NV         0x8FF1\n#define GL_UNSIGNED_INT16_VEC3_NV         0x8FF2\n#define GL_UNSIGNED_INT16_VEC4_NV         0x8FF3\n#define GL_UNSIGNED_INT64_VEC2_NV         0x8FF5\n#define GL_UNSIGNED_INT64_VEC3_NV         0x8FF6\n#define GL_UNSIGNED_INT64_VEC4_NV         0x8FF7\n#define GL_FLOAT16_NV                     0x8FF8\n#define GL_FLOAT16_VEC2_NV                0x8FF9\n#define GL_FLOAT16_VEC3_NV                0x8FFA\n#define GL_FLOAT16_VEC4_NV                0x8FFB\ntypedef void (APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x);\ntypedef void (APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y);\ntypedef void (APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);\ntypedef void (APIENTRYP PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);\ntypedef void (APIENTRYP PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);\ntypedef void (APIENTRYP PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);\ntypedef void (APIENTRYP PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);\ntypedef void (APIENTRYP PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);\ntypedef void (APIENTRYP PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x);\ntypedef void (APIENTRYP PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y);\ntypedef void (APIENTRYP PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);\ntypedef void (APIENTRYP PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);\ntypedef void (APIENTRYP PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);\ntypedef void (APIENTRYP PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);\ntypedef void (APIENTRYP PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);\ntypedef void (APIENTRYP PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);\ntypedef void (APIENTRYP PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT *params);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glUniform1i64NV (GLint location, GLint64EXT x);\nGLAPI void APIENTRY glUniform2i64NV (GLint location, GLint64EXT x, GLint64EXT y);\nGLAPI void APIENTRY glUniform3i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);\nGLAPI void APIENTRY glUniform4i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);\nGLAPI void APIENTRY glUniform1i64vNV (GLint location, GLsizei count, const GLint64EXT *value);\nGLAPI void APIENTRY glUniform2i64vNV (GLint location, GLsizei count, const GLint64EXT *value);\nGLAPI void APIENTRY glUniform3i64vNV (GLint location, GLsizei count, const GLint64EXT *value);\nGLAPI void APIENTRY glUniform4i64vNV (GLint location, GLsizei count, const GLint64EXT *value);\nGLAPI void APIENTRY glUniform1ui64NV (GLint location, GLuint64EXT x);\nGLAPI void APIENTRY glUniform2ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y);\nGLAPI void APIENTRY glUniform3ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);\nGLAPI void APIENTRY glUniform4ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);\nGLAPI void APIENTRY glUniform1ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);\nGLAPI void APIENTRY glUniform2ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);\nGLAPI void APIENTRY glUniform3ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);\nGLAPI void APIENTRY glUniform4ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);\nGLAPI void APIENTRY glGetUniformi64vNV (GLuint program, GLint location, GLint64EXT *params);\nGLAPI void APIENTRY glProgramUniform1i64NV (GLuint program, GLint location, GLint64EXT x);\nGLAPI void APIENTRY glProgramUniform2i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y);\nGLAPI void APIENTRY glProgramUniform3i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);\nGLAPI void APIENTRY glProgramUniform4i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);\nGLAPI void APIENTRY glProgramUniform1i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);\nGLAPI void APIENTRY glProgramUniform2i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);\nGLAPI void APIENTRY glProgramUniform3i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);\nGLAPI void APIENTRY glProgramUniform4i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);\nGLAPI void APIENTRY glProgramUniform1ui64NV (GLuint program, GLint location, GLuint64EXT x);\nGLAPI void APIENTRY glProgramUniform2ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y);\nGLAPI void APIENTRY glProgramUniform3ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);\nGLAPI void APIENTRY glProgramUniform4ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);\nGLAPI void APIENTRY glProgramUniform1ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);\nGLAPI void APIENTRY glProgramUniform2ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);\nGLAPI void APIENTRY glProgramUniform3ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);\nGLAPI void APIENTRY glProgramUniform4ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);\n#endif\n#endif /* GL_NV_gpu_shader5 */\n\n#ifndef GL_NV_internalformat_sample_query\n#define GL_NV_internalformat_sample_query 1\n#define GL_MULTISAMPLES_NV                0x9371\n#define GL_SUPERSAMPLE_SCALE_X_NV         0x9372\n#define GL_SUPERSAMPLE_SCALE_Y_NV         0x9373\n#define GL_CONFORMANT_NV                  0x9374\ntypedef void (APIENTRYP PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei count, GLint *params);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei count, GLint *params);\n#endif\n#endif /* GL_NV_internalformat_sample_query */\n\n#ifndef GL_NV_memory_attachment\n#define GL_NV_memory_attachment 1\n#define GL_ATTACHED_MEMORY_OBJECT_NV      0x95A4\n#define GL_ATTACHED_MEMORY_OFFSET_NV      0x95A5\n#define GL_MEMORY_ATTACHABLE_ALIGNMENT_NV 0x95A6\n#define GL_MEMORY_ATTACHABLE_SIZE_NV      0x95A7\n#define GL_MEMORY_ATTACHABLE_NV           0x95A8\n#define GL_DETACHED_MEMORY_INCARNATION_NV 0x95A9\n#define GL_DETACHED_TEXTURES_NV           0x95AA\n#define GL_DETACHED_BUFFERS_NV            0x95AB\n#define GL_MAX_DETACHED_TEXTURES_NV       0x95AC\n#define GL_MAX_DETACHED_BUFFERS_NV        0x95AD\ntypedef void (APIENTRYP PFNGLGETMEMORYOBJECTDETACHEDRESOURCESUIVNVPROC) (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint *params);\ntypedef void (APIENTRYP PFNGLRESETMEMORYOBJECTPARAMETERNVPROC) (GLuint memory, GLenum pname);\ntypedef void (APIENTRYP PFNGLTEXATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset);\ntypedef void (APIENTRYP PFNGLBUFFERATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset);\ntypedef void (APIENTRYP PFNGLTEXTUREATTACHMEMORYNVPROC) (GLuint texture, GLuint memory, GLuint64 offset);\ntypedef void (APIENTRYP PFNGLNAMEDBUFFERATTACHMEMORYNVPROC) (GLuint buffer, GLuint memory, GLuint64 offset);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glGetMemoryObjectDetachedResourcesuivNV (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint *params);\nGLAPI void APIENTRY glResetMemoryObjectParameterNV (GLuint memory, GLenum pname);\nGLAPI void APIENTRY glTexAttachMemoryNV (GLenum target, GLuint memory, GLuint64 offset);\nGLAPI void APIENTRY glBufferAttachMemoryNV (GLenum target, GLuint memory, GLuint64 offset);\nGLAPI void APIENTRY glTextureAttachMemoryNV (GLuint texture, GLuint memory, GLuint64 offset);\nGLAPI void APIENTRY glNamedBufferAttachMemoryNV (GLuint buffer, GLuint memory, GLuint64 offset);\n#endif\n#endif /* GL_NV_memory_attachment */\n\n#ifndef GL_NV_memory_object_sparse\n#define GL_NV_memory_object_sparse 1\ntypedef void (APIENTRYP PFNGLBUFFERPAGECOMMITMENTMEMNVPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit);\ntypedef void (APIENTRYP PFNGLTEXPAGECOMMITMENTMEMNVPROC) (GLenum target, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit);\ntypedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTMEMNVPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit);\ntypedef void (APIENTRYP PFNGLTEXTUREPAGECOMMITMENTMEMNVPROC) (GLuint texture, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBufferPageCommitmentMemNV (GLenum target, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit);\nGLAPI void APIENTRY glTexPageCommitmentMemNV (GLenum target, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit);\nGLAPI void APIENTRY glNamedBufferPageCommitmentMemNV (GLuint buffer, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit);\nGLAPI void APIENTRY glTexturePageCommitmentMemNV (GLuint texture, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit);\n#endif\n#endif /* GL_NV_memory_object_sparse */\n\n#ifndef GL_NV_mesh_shader\n#define GL_NV_mesh_shader 1\n#define GL_MESH_SHADER_NV                 0x9559\n#define GL_TASK_SHADER_NV                 0x955A\n#define GL_MAX_MESH_UNIFORM_BLOCKS_NV     0x8E60\n#define GL_MAX_MESH_TEXTURE_IMAGE_UNITS_NV 0x8E61\n#define GL_MAX_MESH_IMAGE_UNIFORMS_NV     0x8E62\n#define GL_MAX_MESH_UNIFORM_COMPONENTS_NV 0x8E63\n#define GL_MAX_MESH_ATOMIC_COUNTER_BUFFERS_NV 0x8E64\n#define GL_MAX_MESH_ATOMIC_COUNTERS_NV    0x8E65\n#define GL_MAX_MESH_SHADER_STORAGE_BLOCKS_NV 0x8E66\n#define GL_MAX_COMBINED_MESH_UNIFORM_COMPONENTS_NV 0x8E67\n#define GL_MAX_TASK_UNIFORM_BLOCKS_NV     0x8E68\n#define GL_MAX_TASK_TEXTURE_IMAGE_UNITS_NV 0x8E69\n#define GL_MAX_TASK_IMAGE_UNIFORMS_NV     0x8E6A\n#define GL_MAX_TASK_UNIFORM_COMPONENTS_NV 0x8E6B\n#define GL_MAX_TASK_ATOMIC_COUNTER_BUFFERS_NV 0x8E6C\n#define GL_MAX_TASK_ATOMIC_COUNTERS_NV    0x8E6D\n#define GL_MAX_TASK_SHADER_STORAGE_BLOCKS_NV 0x8E6E\n#define GL_MAX_COMBINED_TASK_UNIFORM_COMPONENTS_NV 0x8E6F\n#define GL_MAX_MESH_WORK_GROUP_INVOCATIONS_NV 0x95A2\n#define GL_MAX_TASK_WORK_GROUP_INVOCATIONS_NV 0x95A3\n#define GL_MAX_MESH_TOTAL_MEMORY_SIZE_NV  0x9536\n#define GL_MAX_TASK_TOTAL_MEMORY_SIZE_NV  0x9537\n#define GL_MAX_MESH_OUTPUT_VERTICES_NV    0x9538\n#define GL_MAX_MESH_OUTPUT_PRIMITIVES_NV  0x9539\n#define GL_MAX_TASK_OUTPUT_COUNT_NV       0x953A\n#define GL_MAX_DRAW_MESH_TASKS_COUNT_NV   0x953D\n#define GL_MAX_MESH_VIEWS_NV              0x9557\n#define GL_MESH_OUTPUT_PER_VERTEX_GRANULARITY_NV 0x92DF\n#define GL_MESH_OUTPUT_PER_PRIMITIVE_GRANULARITY_NV 0x9543\n#define GL_MAX_MESH_WORK_GROUP_SIZE_NV    0x953B\n#define GL_MAX_TASK_WORK_GROUP_SIZE_NV    0x953C\n#define GL_MESH_WORK_GROUP_SIZE_NV        0x953E\n#define GL_TASK_WORK_GROUP_SIZE_NV        0x953F\n#define GL_MESH_VERTICES_OUT_NV           0x9579\n#define GL_MESH_PRIMITIVES_OUT_NV         0x957A\n#define GL_MESH_OUTPUT_TYPE_NV            0x957B\n#define GL_UNIFORM_BLOCK_REFERENCED_BY_MESH_SHADER_NV 0x959C\n#define GL_UNIFORM_BLOCK_REFERENCED_BY_TASK_SHADER_NV 0x959D\n#define GL_REFERENCED_BY_MESH_SHADER_NV   0x95A0\n#define GL_REFERENCED_BY_TASK_SHADER_NV   0x95A1\n#define GL_MESH_SHADER_BIT_NV             0x00000040\n#define GL_TASK_SHADER_BIT_NV             0x00000080\n#define GL_MESH_SUBROUTINE_NV             0x957C\n#define GL_TASK_SUBROUTINE_NV             0x957D\n#define GL_MESH_SUBROUTINE_UNIFORM_NV     0x957E\n#define GL_TASK_SUBROUTINE_UNIFORM_NV     0x957F\n#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_MESH_SHADER_NV 0x959E\n#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TASK_SHADER_NV 0x959F\ntypedef void (APIENTRYP PFNGLDRAWMESHTASKSNVPROC) (GLuint first, GLuint count);\ntypedef void (APIENTRYP PFNGLDRAWMESHTASKSINDIRECTNVPROC) (GLintptr indirect);\ntypedef void (APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTNVPROC) (GLintptr indirect, GLsizei drawcount, GLsizei stride);\ntypedef void (APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTNVPROC) (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glDrawMeshTasksNV (GLuint first, GLuint count);\nGLAPI void APIENTRY glDrawMeshTasksIndirectNV (GLintptr indirect);\nGLAPI void APIENTRY glMultiDrawMeshTasksIndirectNV (GLintptr indirect, GLsizei drawcount, GLsizei stride);\nGLAPI void APIENTRY glMultiDrawMeshTasksIndirectCountNV (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);\n#endif\n#endif /* GL_NV_mesh_shader */\n\n#ifndef GL_NV_path_rendering\n#define GL_NV_path_rendering 1\n#define GL_PATH_FORMAT_SVG_NV             0x9070\n#define GL_PATH_FORMAT_PS_NV              0x9071\n#define GL_STANDARD_FONT_NAME_NV          0x9072\n#define GL_SYSTEM_FONT_NAME_NV            0x9073\n#define GL_FILE_NAME_NV                   0x9074\n#define GL_PATH_STROKE_WIDTH_NV           0x9075\n#define GL_PATH_END_CAPS_NV               0x9076\n#define GL_PATH_INITIAL_END_CAP_NV        0x9077\n#define GL_PATH_TERMINAL_END_CAP_NV       0x9078\n#define GL_PATH_JOIN_STYLE_NV             0x9079\n#define GL_PATH_MITER_LIMIT_NV            0x907A\n#define GL_PATH_DASH_CAPS_NV              0x907B\n#define GL_PATH_INITIAL_DASH_CAP_NV       0x907C\n#define GL_PATH_TERMINAL_DASH_CAP_NV      0x907D\n#define GL_PATH_DASH_OFFSET_NV            0x907E\n#define GL_PATH_CLIENT_LENGTH_NV          0x907F\n#define GL_PATH_FILL_MODE_NV              0x9080\n#define GL_PATH_FILL_MASK_NV              0x9081\n#define GL_PATH_FILL_COVER_MODE_NV        0x9082\n#define GL_PATH_STROKE_COVER_MODE_NV      0x9083\n#define GL_PATH_STROKE_MASK_NV            0x9084\n#define GL_COUNT_UP_NV                    0x9088\n#define GL_COUNT_DOWN_NV                  0x9089\n#define GL_PATH_OBJECT_BOUNDING_BOX_NV    0x908A\n#define GL_CONVEX_HULL_NV                 0x908B\n#define GL_BOUNDING_BOX_NV                0x908D\n#define GL_TRANSLATE_X_NV                 0x908E\n#define GL_TRANSLATE_Y_NV                 0x908F\n#define GL_TRANSLATE_2D_NV                0x9090\n#define GL_TRANSLATE_3D_NV                0x9091\n#define GL_AFFINE_2D_NV                   0x9092\n#define GL_AFFINE_3D_NV                   0x9094\n#define GL_TRANSPOSE_AFFINE_2D_NV         0x9096\n#define GL_TRANSPOSE_AFFINE_3D_NV         0x9098\n#define GL_UTF8_NV                        0x909A\n#define GL_UTF16_NV                       0x909B\n#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C\n#define GL_PATH_COMMAND_COUNT_NV          0x909D\n#define GL_PATH_COORD_COUNT_NV            0x909E\n#define GL_PATH_DASH_ARRAY_COUNT_NV       0x909F\n#define GL_PATH_COMPUTED_LENGTH_NV        0x90A0\n#define GL_PATH_FILL_BOUNDING_BOX_NV      0x90A1\n#define GL_PATH_STROKE_BOUNDING_BOX_NV    0x90A2\n#define GL_SQUARE_NV                      0x90A3\n#define GL_ROUND_NV                       0x90A4\n#define GL_TRIANGULAR_NV                  0x90A5\n#define GL_BEVEL_NV                       0x90A6\n#define GL_MITER_REVERT_NV                0x90A7\n#define GL_MITER_TRUNCATE_NV              0x90A8\n#define GL_SKIP_MISSING_GLYPH_NV          0x90A9\n#define GL_USE_MISSING_GLYPH_NV           0x90AA\n#define GL_PATH_ERROR_POSITION_NV         0x90AB\n#define GL_ACCUM_ADJACENT_PAIRS_NV        0x90AD\n#define GL_ADJACENT_PAIRS_NV              0x90AE\n#define GL_FIRST_TO_REST_NV               0x90AF\n#define GL_PATH_GEN_MODE_NV               0x90B0\n#define GL_PATH_GEN_COEFF_NV              0x90B1\n#define GL_PATH_GEN_COMPONENTS_NV         0x90B3\n#define GL_PATH_STENCIL_FUNC_NV           0x90B7\n#define GL_PATH_STENCIL_REF_NV            0x90B8\n#define GL_PATH_STENCIL_VALUE_MASK_NV     0x90B9\n#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD\n#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE\n#define GL_PATH_COVER_DEPTH_FUNC_NV       0x90BF\n#define GL_PATH_DASH_OFFSET_RESET_NV      0x90B4\n#define GL_MOVE_TO_RESETS_NV              0x90B5\n#define GL_MOVE_TO_CONTINUES_NV           0x90B6\n#define GL_CLOSE_PATH_NV                  0x00\n#define GL_MOVE_TO_NV                     0x02\n#define GL_RELATIVE_MOVE_TO_NV            0x03\n#define GL_LINE_TO_NV                     0x04\n#define GL_RELATIVE_LINE_TO_NV            0x05\n#define GL_HORIZONTAL_LINE_TO_NV          0x06\n#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07\n#define GL_VERTICAL_LINE_TO_NV            0x08\n#define GL_RELATIVE_VERTICAL_LINE_TO_NV   0x09\n#define GL_QUADRATIC_CURVE_TO_NV          0x0A\n#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B\n#define GL_CUBIC_CURVE_TO_NV              0x0C\n#define GL_RELATIVE_CUBIC_CURVE_TO_NV     0x0D\n#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV   0x0E\n#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F\n#define GL_SMOOTH_CUBIC_CURVE_TO_NV       0x10\n#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11\n#define GL_SMALL_CCW_ARC_TO_NV            0x12\n#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV   0x13\n#define GL_SMALL_CW_ARC_TO_NV             0x14\n#define GL_RELATIVE_SMALL_CW_ARC_TO_NV    0x15\n#define GL_LARGE_CCW_ARC_TO_NV            0x16\n#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV   0x17\n#define GL_LARGE_CW_ARC_TO_NV             0x18\n#define GL_RELATIVE_LARGE_CW_ARC_TO_NV    0x19\n#define GL_RESTART_PATH_NV                0xF0\n#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV    0xF2\n#define GL_DUP_LAST_CUBIC_CURVE_TO_NV     0xF4\n#define GL_RECT_NV                        0xF6\n#define GL_CIRCULAR_CCW_ARC_TO_NV         0xF8\n#define GL_CIRCULAR_CW_ARC_TO_NV          0xFA\n#define GL_CIRCULAR_TANGENT_ARC_TO_NV     0xFC\n#define GL_ARC_TO_NV                      0xFE\n#define GL_RELATIVE_ARC_TO_NV             0xFF\n#define GL_BOLD_BIT_NV                    0x01\n#define GL_ITALIC_BIT_NV                  0x02\n#define GL_GLYPH_WIDTH_BIT_NV             0x01\n#define GL_GLYPH_HEIGHT_BIT_NV            0x02\n#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04\n#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08\n#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10\n#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20\n#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40\n#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80\n#define GL_GLYPH_HAS_KERNING_BIT_NV       0x100\n#define GL_FONT_X_MIN_BOUNDS_BIT_NV       0x00010000\n#define GL_FONT_Y_MIN_BOUNDS_BIT_NV       0x00020000\n#define GL_FONT_X_MAX_BOUNDS_BIT_NV       0x00040000\n#define GL_FONT_Y_MAX_BOUNDS_BIT_NV       0x00080000\n#define GL_FONT_UNITS_PER_EM_BIT_NV       0x00100000\n#define GL_FONT_ASCENDER_BIT_NV           0x00200000\n#define GL_FONT_DESCENDER_BIT_NV          0x00400000\n#define GL_FONT_HEIGHT_BIT_NV             0x00800000\n#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV  0x01000000\n#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000\n#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000\n#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000\n#define GL_FONT_HAS_KERNING_BIT_NV        0x10000000\n#define GL_ROUNDED_RECT_NV                0xE8\n#define GL_RELATIVE_ROUNDED_RECT_NV       0xE9\n#define GL_ROUNDED_RECT2_NV               0xEA\n#define GL_RELATIVE_ROUNDED_RECT2_NV      0xEB\n#define GL_ROUNDED_RECT4_NV               0xEC\n#define GL_RELATIVE_ROUNDED_RECT4_NV      0xED\n#define GL_ROUNDED_RECT8_NV               0xEE\n#define GL_RELATIVE_ROUNDED_RECT8_NV      0xEF\n#define GL_RELATIVE_RECT_NV               0xF7\n#define GL_FONT_GLYPHS_AVAILABLE_NV       0x9368\n#define GL_FONT_TARGET_UNAVAILABLE_NV     0x9369\n#define GL_FONT_UNAVAILABLE_NV            0x936A\n#define GL_FONT_UNINTELLIGIBLE_NV         0x936B\n#define GL_CONIC_CURVE_TO_NV              0x1A\n#define GL_RELATIVE_CONIC_CURVE_TO_NV     0x1B\n#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV  0x20000000\n#define GL_STANDARD_FONT_FORMAT_NV        0x936C\n#define GL_PATH_PROJECTION_NV             0x1701\n#define GL_PATH_MODELVIEW_NV              0x1700\n#define GL_PATH_MODELVIEW_STACK_DEPTH_NV  0x0BA3\n#define GL_PATH_MODELVIEW_MATRIX_NV       0x0BA6\n#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36\n#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3\n#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4\n#define GL_PATH_PROJECTION_MATRIX_NV      0x0BA7\n#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38\n#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4\n#define GL_FRAGMENT_INPUT_NV              0x936D\ntypedef GLuint (APIENTRYP PFNGLGENPATHSNVPROC) (GLsizei range);\ntypedef void (APIENTRYP PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range);\ntypedef GLboolean (APIENTRYP PFNGLISPATHNVPROC) (GLuint path);\ntypedef void (APIENTRYP PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);\ntypedef void (APIENTRYP PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords);\ntypedef void (APIENTRYP PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);\ntypedef void (APIENTRYP PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords);\ntypedef void (APIENTRYP PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void *pathString);\ntypedef void (APIENTRYP PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);\ntypedef void (APIENTRYP PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);\ntypedef void (APIENTRYP PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights);\ntypedef void (APIENTRYP PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath);\ntypedef void (APIENTRYP PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight);\ntypedef void (APIENTRYP PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues);\ntypedef void (APIENTRYP PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint *value);\ntypedef void (APIENTRYP PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value);\ntypedef void (APIENTRYP PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat *value);\ntypedef void (APIENTRYP PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value);\ntypedef void (APIENTRYP PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat *dashArray);\ntypedef void (APIENTRYP PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask);\ntypedef void (APIENTRYP PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units);\ntypedef void (APIENTRYP PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask);\ntypedef void (APIENTRYP PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask);\ntypedef void (APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues);\ntypedef void (APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues);\ntypedef void (APIENTRYP PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func);\ntypedef void (APIENTRYP PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode);\ntypedef void (APIENTRYP PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode);\ntypedef void (APIENTRYP PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);\ntypedef void (APIENTRYP PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);\ntypedef void (APIENTRYP PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint *value);\ntypedef void (APIENTRYP PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat *value);\ntypedef void (APIENTRYP PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte *commands);\ntypedef void (APIENTRYP PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat *coords);\ntypedef void (APIENTRYP PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat *dashArray);\ntypedef void (APIENTRYP PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics);\ntypedef void (APIENTRYP PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics);\ntypedef void (APIENTRYP PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing);\ntypedef GLboolean (APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y);\ntypedef GLboolean (APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y);\ntypedef GLfloat (APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments);\ntypedef GLboolean (APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY);\ntypedef void (APIENTRYP PFNGLMATRIXLOAD3X2FNVPROC) (GLenum matrixMode, const GLfloat *m);\ntypedef void (APIENTRYP PFNGLMATRIXLOAD3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);\ntypedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);\ntypedef void (APIENTRYP PFNGLMATRIXMULT3X2FNVPROC) (GLenum matrixMode, const GLfloat *m);\ntypedef void (APIENTRYP PFNGLMATRIXMULT3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);\ntypedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);\ntypedef void (APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode);\ntypedef void (APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode);\ntypedef void (APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);\ntypedef void (APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);\ntypedef GLenum (APIENTRYP PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint *baseAndCount);\ntypedef GLenum (APIENTRYP PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);\ntypedef GLenum (APIENTRYP PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);\ntypedef void (APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs);\ntypedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLfloat *params);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI GLuint APIENTRY glGenPathsNV (GLsizei range);\nGLAPI void APIENTRY glDeletePathsNV (GLuint path, GLsizei range);\nGLAPI GLboolean APIENTRY glIsPathNV (GLuint path);\nGLAPI void APIENTRY glPathCommandsNV (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);\nGLAPI void APIENTRY glPathCoordsNV (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords);\nGLAPI void APIENTRY glPathSubCommandsNV (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);\nGLAPI void APIENTRY glPathSubCoordsNV (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords);\nGLAPI void APIENTRY glPathStringNV (GLuint path, GLenum format, GLsizei length, const void *pathString);\nGLAPI void APIENTRY glPathGlyphsNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);\nGLAPI void APIENTRY glPathGlyphRangeNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);\nGLAPI void APIENTRY glWeightPathsNV (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights);\nGLAPI void APIENTRY glCopyPathNV (GLuint resultPath, GLuint srcPath);\nGLAPI void APIENTRY glInterpolatePathsNV (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight);\nGLAPI void APIENTRY glTransformPathNV (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues);\nGLAPI void APIENTRY glPathParameterivNV (GLuint path, GLenum pname, const GLint *value);\nGLAPI void APIENTRY glPathParameteriNV (GLuint path, GLenum pname, GLint value);\nGLAPI void APIENTRY glPathParameterfvNV (GLuint path, GLenum pname, const GLfloat *value);\nGLAPI void APIENTRY glPathParameterfNV (GLuint path, GLenum pname, GLfloat value);\nGLAPI void APIENTRY glPathDashArrayNV (GLuint path, GLsizei dashCount, const GLfloat *dashArray);\nGLAPI void APIENTRY glPathStencilFuncNV (GLenum func, GLint ref, GLuint mask);\nGLAPI void APIENTRY glPathStencilDepthOffsetNV (GLfloat factor, GLfloat units);\nGLAPI void APIENTRY glStencilFillPathNV (GLuint path, GLenum fillMode, GLuint mask);\nGLAPI void APIENTRY glStencilStrokePathNV (GLuint path, GLint reference, GLuint mask);\nGLAPI void APIENTRY glStencilFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues);\nGLAPI void APIENTRY glStencilStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues);\nGLAPI void APIENTRY glPathCoverDepthFuncNV (GLenum func);\nGLAPI void APIENTRY glCoverFillPathNV (GLuint path, GLenum coverMode);\nGLAPI void APIENTRY glCoverStrokePathNV (GLuint path, GLenum coverMode);\nGLAPI void APIENTRY glCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);\nGLAPI void APIENTRY glCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);\nGLAPI void APIENTRY glGetPathParameterivNV (GLuint path, GLenum pname, GLint *value);\nGLAPI void APIENTRY glGetPathParameterfvNV (GLuint path, GLenum pname, GLfloat *value);\nGLAPI void APIENTRY glGetPathCommandsNV (GLuint path, GLubyte *commands);\nGLAPI void APIENTRY glGetPathCoordsNV (GLuint path, GLfloat *coords);\nGLAPI void APIENTRY glGetPathDashArrayNV (GLuint path, GLfloat *dashArray);\nGLAPI void APIENTRY glGetPathMetricsNV (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics);\nGLAPI void APIENTRY glGetPathMetricRangeNV (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics);\nGLAPI void APIENTRY glGetPathSpacingNV (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing);\nGLAPI GLboolean APIENTRY glIsPointInFillPathNV (GLuint path, GLuint mask, GLfloat x, GLfloat y);\nGLAPI GLboolean APIENTRY glIsPointInStrokePathNV (GLuint path, GLfloat x, GLfloat y);\nGLAPI GLfloat APIENTRY glGetPathLengthNV (GLuint path, GLsizei startSegment, GLsizei numSegments);\nGLAPI GLboolean APIENTRY glPointAlongPathNV (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY);\nGLAPI void APIENTRY glMatrixLoad3x2fNV (GLenum matrixMode, const GLfloat *m);\nGLAPI void APIENTRY glMatrixLoad3x3fNV (GLenum matrixMode, const GLfloat *m);\nGLAPI void APIENTRY glMatrixLoadTranspose3x3fNV (GLenum matrixMode, const GLfloat *m);\nGLAPI void APIENTRY glMatrixMult3x2fNV (GLenum matrixMode, const GLfloat *m);\nGLAPI void APIENTRY glMatrixMult3x3fNV (GLenum matrixMode, const GLfloat *m);\nGLAPI void APIENTRY glMatrixMultTranspose3x3fNV (GLenum matrixMode, const GLfloat *m);\nGLAPI void APIENTRY glStencilThenCoverFillPathNV (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode);\nGLAPI void APIENTRY glStencilThenCoverStrokePathNV (GLuint path, GLint reference, GLuint mask, GLenum coverMode);\nGLAPI void APIENTRY glStencilThenCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);\nGLAPI void APIENTRY glStencilThenCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);\nGLAPI GLenum APIENTRY glPathGlyphIndexRangeNV (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint *baseAndCount);\nGLAPI GLenum APIENTRY glPathGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);\nGLAPI GLenum APIENTRY glPathMemoryGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);\nGLAPI void APIENTRY glProgramPathFragmentInputGenNV (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs);\nGLAPI void APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLfloat *params);\n#endif\n#endif /* GL_NV_path_rendering */\n\n#ifndef GL_NV_path_rendering_shared_edge\n#define GL_NV_path_rendering_shared_edge 1\n#define GL_SHARED_EDGE_NV                 0xC0\n#endif /* GL_NV_path_rendering_shared_edge */\n\n#ifndef GL_NV_primitive_shading_rate\n#define GL_NV_primitive_shading_rate 1\n#define GL_SHADING_RATE_IMAGE_PER_PRIMITIVE_NV 0x95B1\n#define GL_SHADING_RATE_IMAGE_PALETTE_COUNT_NV 0x95B2\n#endif /* GL_NV_primitive_shading_rate */\n\n#ifndef GL_NV_representative_fragment_test\n#define GL_NV_representative_fragment_test 1\n#define GL_REPRESENTATIVE_FRAGMENT_TEST_NV 0x937F\n#endif /* GL_NV_representative_fragment_test */\n\n#ifndef GL_NV_sample_locations\n#define GL_NV_sample_locations 1\n#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D\n#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV 0x933E\n#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV 0x933F\n#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV 0x9340\n#define GL_SAMPLE_LOCATION_NV             0x8E50\n#define GL_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9341\n#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV 0x9342\n#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV 0x9343\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v);\ntypedef void (APIENTRYP PFNGLRESOLVEDEPTHVALUESNVPROC) (void);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glFramebufferSampleLocationsfvNV (GLenum target, GLuint start, GLsizei count, const GLfloat *v);\nGLAPI void APIENTRY glNamedFramebufferSampleLocationsfvNV (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v);\nGLAPI void APIENTRY glResolveDepthValuesNV (void);\n#endif\n#endif /* GL_NV_sample_locations */\n\n#ifndef GL_NV_sample_mask_override_coverage\n#define GL_NV_sample_mask_override_coverage 1\n#endif /* GL_NV_sample_mask_override_coverage */\n\n#ifndef GL_NV_scissor_exclusive\n#define GL_NV_scissor_exclusive 1\n#define GL_SCISSOR_TEST_EXCLUSIVE_NV      0x9555\n#define GL_SCISSOR_BOX_EXCLUSIVE_NV       0x9556\ntypedef void (APIENTRYP PFNGLSCISSOREXCLUSIVENVPROC) (GLint x, GLint y, GLsizei width, GLsizei height);\ntypedef void (APIENTRYP PFNGLSCISSOREXCLUSIVEARRAYVNVPROC) (GLuint first, GLsizei count, const GLint *v);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glScissorExclusiveNV (GLint x, GLint y, GLsizei width, GLsizei height);\nGLAPI void APIENTRY glScissorExclusiveArrayvNV (GLuint first, GLsizei count, const GLint *v);\n#endif\n#endif /* GL_NV_scissor_exclusive */\n\n#ifndef GL_NV_shader_atomic_counters\n#define GL_NV_shader_atomic_counters 1\n#endif /* GL_NV_shader_atomic_counters */\n\n#ifndef GL_NV_shader_atomic_float\n#define GL_NV_shader_atomic_float 1\n#endif /* GL_NV_shader_atomic_float */\n\n#ifndef GL_NV_shader_atomic_float64\n#define GL_NV_shader_atomic_float64 1\n#endif /* GL_NV_shader_atomic_float64 */\n\n#ifndef GL_NV_shader_atomic_fp16_vector\n#define GL_NV_shader_atomic_fp16_vector 1\n#endif /* GL_NV_shader_atomic_fp16_vector */\n\n#ifndef GL_NV_shader_atomic_int64\n#define GL_NV_shader_atomic_int64 1\n#endif /* GL_NV_shader_atomic_int64 */\n\n#ifndef GL_NV_shader_buffer_load\n#define GL_NV_shader_buffer_load 1\n#define GL_BUFFER_GPU_ADDRESS_NV          0x8F1D\n#define GL_GPU_ADDRESS_NV                 0x8F34\n#define GL_MAX_SHADER_BUFFER_ADDRESS_NV   0x8F35\ntypedef void (APIENTRYP PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access);\ntypedef void (APIENTRYP PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target);\ntypedef GLboolean (APIENTRYP PFNGLISBUFFERRESIDENTNVPROC) (GLenum target);\ntypedef void (APIENTRYP PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access);\ntypedef void (APIENTRYP PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer);\ntypedef GLboolean (APIENTRYP PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer);\ntypedef void (APIENTRYP PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT *params);\ntypedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT *params);\ntypedef void (APIENTRYP PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT *result);\ntypedef void (APIENTRYP PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value);\ntypedef void (APIENTRYP PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);\ntypedef void (APIENTRYP PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT *params);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value);\ntypedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glMakeBufferResidentNV (GLenum target, GLenum access);\nGLAPI void APIENTRY glMakeBufferNonResidentNV (GLenum target);\nGLAPI GLboolean APIENTRY glIsBufferResidentNV (GLenum target);\nGLAPI void APIENTRY glMakeNamedBufferResidentNV (GLuint buffer, GLenum access);\nGLAPI void APIENTRY glMakeNamedBufferNonResidentNV (GLuint buffer);\nGLAPI GLboolean APIENTRY glIsNamedBufferResidentNV (GLuint buffer);\nGLAPI void APIENTRY glGetBufferParameterui64vNV (GLenum target, GLenum pname, GLuint64EXT *params);\nGLAPI void APIENTRY glGetNamedBufferParameterui64vNV (GLuint buffer, GLenum pname, GLuint64EXT *params);\nGLAPI void APIENTRY glGetIntegerui64vNV (GLenum value, GLuint64EXT *result);\nGLAPI void APIENTRY glUniformui64NV (GLint location, GLuint64EXT value);\nGLAPI void APIENTRY glUniformui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);\nGLAPI void APIENTRY glGetUniformui64vNV (GLuint program, GLint location, GLuint64EXT *params);\nGLAPI void APIENTRY glProgramUniformui64NV (GLuint program, GLint location, GLuint64EXT value);\nGLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);\n#endif\n#endif /* GL_NV_shader_buffer_load */\n\n#ifndef GL_NV_shader_buffer_store\n#define GL_NV_shader_buffer_store 1\n#define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010\n#endif /* GL_NV_shader_buffer_store */\n\n#ifndef GL_NV_shader_subgroup_partitioned\n#define GL_NV_shader_subgroup_partitioned 1\n#define GL_SUBGROUP_FEATURE_PARTITIONED_BIT_NV 0x00000100\n#endif /* GL_NV_shader_subgroup_partitioned */\n\n#ifndef GL_NV_shader_texture_footprint\n#define GL_NV_shader_texture_footprint 1\n#endif /* GL_NV_shader_texture_footprint */\n\n#ifndef GL_NV_shader_thread_group\n#define GL_NV_shader_thread_group 1\n#define GL_WARP_SIZE_NV                   0x9339\n#define GL_WARPS_PER_SM_NV                0x933A\n#define GL_SM_COUNT_NV                    0x933B\n#endif /* GL_NV_shader_thread_group */\n\n#ifndef GL_NV_shader_thread_shuffle\n#define GL_NV_shader_thread_shuffle 1\n#endif /* GL_NV_shader_thread_shuffle */\n\n#ifndef GL_NV_shading_rate_image\n#define GL_NV_shading_rate_image 1\n#define GL_SHADING_RATE_IMAGE_NV          0x9563\n#define GL_SHADING_RATE_NO_INVOCATIONS_NV 0x9564\n#define GL_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV 0x9565\n#define GL_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV 0x9566\n#define GL_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV 0x9567\n#define GL_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV 0x9568\n#define GL_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV 0x9569\n#define GL_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV 0x956A\n#define GL_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV 0x956B\n#define GL_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV 0x956C\n#define GL_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV 0x956D\n#define GL_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV 0x956E\n#define GL_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV 0x956F\n#define GL_SHADING_RATE_IMAGE_BINDING_NV  0x955B\n#define GL_SHADING_RATE_IMAGE_TEXEL_WIDTH_NV 0x955C\n#define GL_SHADING_RATE_IMAGE_TEXEL_HEIGHT_NV 0x955D\n#define GL_SHADING_RATE_IMAGE_PALETTE_SIZE_NV 0x955E\n#define GL_MAX_COARSE_FRAGMENT_SAMPLES_NV 0x955F\n#define GL_SHADING_RATE_SAMPLE_ORDER_DEFAULT_NV 0x95AE\n#define GL_SHADING_RATE_SAMPLE_ORDER_PIXEL_MAJOR_NV 0x95AF\n#define GL_SHADING_RATE_SAMPLE_ORDER_SAMPLE_MAJOR_NV 0x95B0\ntypedef void (APIENTRYP PFNGLBINDSHADINGRATEIMAGENVPROC) (GLuint texture);\ntypedef void (APIENTRYP PFNGLGETSHADINGRATEIMAGEPALETTENVPROC) (GLuint viewport, GLuint entry, GLenum *rate);\ntypedef void (APIENTRYP PFNGLGETSHADINGRATESAMPLELOCATIONIVNVPROC) (GLenum rate, GLuint samples, GLuint index, GLint *location);\ntypedef void (APIENTRYP PFNGLSHADINGRATEIMAGEBARRIERNVPROC) (GLboolean synchronize);\ntypedef void (APIENTRYP PFNGLSHADINGRATEIMAGEPALETTENVPROC) (GLuint viewport, GLuint first, GLsizei count, const GLenum *rates);\ntypedef void (APIENTRYP PFNGLSHADINGRATESAMPLEORDERNVPROC) (GLenum order);\ntypedef void (APIENTRYP PFNGLSHADINGRATESAMPLEORDERCUSTOMNVPROC) (GLenum rate, GLuint samples, const GLint *locations);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBindShadingRateImageNV (GLuint texture);\nGLAPI void APIENTRY glGetShadingRateImagePaletteNV (GLuint viewport, GLuint entry, GLenum *rate);\nGLAPI void APIENTRY glGetShadingRateSampleLocationivNV (GLenum rate, GLuint samples, GLuint index, GLint *location);\nGLAPI void APIENTRY glShadingRateImageBarrierNV (GLboolean synchronize);\nGLAPI void APIENTRY glShadingRateImagePaletteNV (GLuint viewport, GLuint first, GLsizei count, const GLenum *rates);\nGLAPI void APIENTRY glShadingRateSampleOrderNV (GLenum order);\nGLAPI void APIENTRY glShadingRateSampleOrderCustomNV (GLenum rate, GLuint samples, const GLint *locations);\n#endif\n#endif /* GL_NV_shading_rate_image */\n\n#ifndef GL_NV_stereo_view_rendering\n#define GL_NV_stereo_view_rendering 1\n#endif /* GL_NV_stereo_view_rendering */\n\n#ifndef GL_NV_texture_barrier\n#define GL_NV_texture_barrier 1\ntypedef void (APIENTRYP PFNGLTEXTUREBARRIERNVPROC) (void);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glTextureBarrierNV (void);\n#endif\n#endif /* GL_NV_texture_barrier */\n\n#ifndef GL_NV_texture_rectangle_compressed\n#define GL_NV_texture_rectangle_compressed 1\n#endif /* GL_NV_texture_rectangle_compressed */\n\n#ifndef GL_NV_uniform_buffer_std430_layout\n#define GL_NV_uniform_buffer_std430_layout 1\n#endif /* GL_NV_uniform_buffer_std430_layout */\n\n#ifndef GL_NV_uniform_buffer_unified_memory\n#define GL_NV_uniform_buffer_unified_memory 1\n#define GL_UNIFORM_BUFFER_UNIFIED_NV      0x936E\n#define GL_UNIFORM_BUFFER_ADDRESS_NV      0x936F\n#define GL_UNIFORM_BUFFER_LENGTH_NV       0x9370\n#endif /* GL_NV_uniform_buffer_unified_memory */\n\n#ifndef GL_NV_vertex_attrib_integer_64bit\n#define GL_NV_vertex_attrib_integer_64bit 1\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT *v);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT *v);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT *params);\ntypedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT *params);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glVertexAttribL1i64NV (GLuint index, GLint64EXT x);\nGLAPI void APIENTRY glVertexAttribL2i64NV (GLuint index, GLint64EXT x, GLint64EXT y);\nGLAPI void APIENTRY glVertexAttribL3i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z);\nGLAPI void APIENTRY glVertexAttribL4i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);\nGLAPI void APIENTRY glVertexAttribL1i64vNV (GLuint index, const GLint64EXT *v);\nGLAPI void APIENTRY glVertexAttribL2i64vNV (GLuint index, const GLint64EXT *v);\nGLAPI void APIENTRY glVertexAttribL3i64vNV (GLuint index, const GLint64EXT *v);\nGLAPI void APIENTRY glVertexAttribL4i64vNV (GLuint index, const GLint64EXT *v);\nGLAPI void APIENTRY glVertexAttribL1ui64NV (GLuint index, GLuint64EXT x);\nGLAPI void APIENTRY glVertexAttribL2ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y);\nGLAPI void APIENTRY glVertexAttribL3ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);\nGLAPI void APIENTRY glVertexAttribL4ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);\nGLAPI void APIENTRY glVertexAttribL1ui64vNV (GLuint index, const GLuint64EXT *v);\nGLAPI void APIENTRY glVertexAttribL2ui64vNV (GLuint index, const GLuint64EXT *v);\nGLAPI void APIENTRY glVertexAttribL3ui64vNV (GLuint index, const GLuint64EXT *v);\nGLAPI void APIENTRY glVertexAttribL4ui64vNV (GLuint index, const GLuint64EXT *v);\nGLAPI void APIENTRY glGetVertexAttribLi64vNV (GLuint index, GLenum pname, GLint64EXT *params);\nGLAPI void APIENTRY glGetVertexAttribLui64vNV (GLuint index, GLenum pname, GLuint64EXT *params);\nGLAPI void APIENTRY glVertexAttribLFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride);\n#endif\n#endif /* GL_NV_vertex_attrib_integer_64bit */\n\n#ifndef GL_NV_vertex_buffer_unified_memory\n#define GL_NV_vertex_buffer_unified_memory 1\n#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E\n#define GL_ELEMENT_ARRAY_UNIFIED_NV       0x8F1F\n#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20\n#define GL_VERTEX_ARRAY_ADDRESS_NV        0x8F21\n#define GL_NORMAL_ARRAY_ADDRESS_NV        0x8F22\n#define GL_COLOR_ARRAY_ADDRESS_NV         0x8F23\n#define GL_INDEX_ARRAY_ADDRESS_NV         0x8F24\n#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25\n#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV     0x8F26\n#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27\n#define GL_FOG_COORD_ARRAY_ADDRESS_NV     0x8F28\n#define GL_ELEMENT_ARRAY_ADDRESS_NV       0x8F29\n#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV  0x8F2A\n#define GL_VERTEX_ARRAY_LENGTH_NV         0x8F2B\n#define GL_NORMAL_ARRAY_LENGTH_NV         0x8F2C\n#define GL_COLOR_ARRAY_LENGTH_NV          0x8F2D\n#define GL_INDEX_ARRAY_LENGTH_NV          0x8F2E\n#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV  0x8F2F\n#define GL_EDGE_FLAG_ARRAY_LENGTH_NV      0x8F30\n#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31\n#define GL_FOG_COORD_ARRAY_LENGTH_NV      0x8F32\n#define GL_ELEMENT_ARRAY_LENGTH_NV        0x8F33\n#define GL_DRAW_INDIRECT_UNIFIED_NV       0x8F40\n#define GL_DRAW_INDIRECT_ADDRESS_NV       0x8F41\n#define GL_DRAW_INDIRECT_LENGTH_NV        0x8F42\ntypedef void (APIENTRYP PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length);\ntypedef void (APIENTRYP PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);\ntypedef void (APIENTRYP PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride);\ntypedef void (APIENTRYP PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);\ntypedef void (APIENTRYP PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride);\ntypedef void (APIENTRYP PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);\ntypedef void (APIENTRYP PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride);\ntypedef void (APIENTRYP PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);\ntypedef void (APIENTRYP PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride);\ntypedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride);\ntypedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glBufferAddressRangeNV (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length);\nGLAPI void APIENTRY glVertexFormatNV (GLint size, GLenum type, GLsizei stride);\nGLAPI void APIENTRY glNormalFormatNV (GLenum type, GLsizei stride);\nGLAPI void APIENTRY glColorFormatNV (GLint size, GLenum type, GLsizei stride);\nGLAPI void APIENTRY glIndexFormatNV (GLenum type, GLsizei stride);\nGLAPI void APIENTRY glTexCoordFormatNV (GLint size, GLenum type, GLsizei stride);\nGLAPI void APIENTRY glEdgeFlagFormatNV (GLsizei stride);\nGLAPI void APIENTRY glSecondaryColorFormatNV (GLint size, GLenum type, GLsizei stride);\nGLAPI void APIENTRY glFogCoordFormatNV (GLenum type, GLsizei stride);\nGLAPI void APIENTRY glVertexAttribFormatNV (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride);\nGLAPI void APIENTRY glVertexAttribIFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride);\nGLAPI void APIENTRY glGetIntegerui64i_vNV (GLenum value, GLuint index, GLuint64EXT *result);\n#endif\n#endif /* GL_NV_vertex_buffer_unified_memory */\n\n#ifndef GL_NV_viewport_array2\n#define GL_NV_viewport_array2 1\n#endif /* GL_NV_viewport_array2 */\n\n#ifndef GL_NV_viewport_swizzle\n#define GL_NV_viewport_swizzle 1\n#define GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV 0x9350\n#define GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV 0x9351\n#define GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV 0x9352\n#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV 0x9353\n#define GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV 0x9354\n#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV 0x9355\n#define GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV 0x9356\n#define GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV 0x9357\n#define GL_VIEWPORT_SWIZZLE_X_NV          0x9358\n#define GL_VIEWPORT_SWIZZLE_Y_NV          0x9359\n#define GL_VIEWPORT_SWIZZLE_Z_NV          0x935A\n#define GL_VIEWPORT_SWIZZLE_W_NV          0x935B\ntypedef void (APIENTRYP PFNGLVIEWPORTSWIZZLENVPROC) (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glViewportSwizzleNV (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew);\n#endif\n#endif /* GL_NV_viewport_swizzle */\n\n#ifndef GL_OVR_multiview\n#define GL_OVR_multiview 1\n#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630\n#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632\n#define GL_MAX_VIEWS_OVR                  0x9631\n#define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633\ntypedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews);\n#ifdef GL_GLEXT_PROTOTYPES\nGLAPI void APIENTRY glFramebufferTextureMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews);\n#endif\n#endif /* GL_OVR_multiview */\n\n#ifndef GL_OVR_multiview2\n#define GL_OVR_multiview2 1\n#endif /* GL_OVR_multiview2 */\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "external/include/KHR/khrplatform.h",
    "content": "#ifndef __khrplatform_h_\n#define __khrplatform_h_\n\n/*\n** Copyright (c) 2008-2018 The Khronos Group Inc.\n**\n** Permission is hereby granted, free of charge, to any person obtaining a\n** copy of this software and/or associated documentation files (the\n** \"Materials\"), to deal in the Materials without restriction, including\n** without limitation the rights to use, copy, modify, merge, publish,\n** distribute, sublicense, and/or sell copies of the Materials, and to\n** permit persons to whom the Materials are furnished to do so, subject to\n** the following conditions:\n**\n** The above copyright notice and this permission notice shall be included\n** in all copies or substantial portions of the Materials.\n**\n** THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.\n*/\n\n/* Khronos platform-specific types and definitions.\n *\n * The master copy of khrplatform.h is maintained in the Khronos EGL\n * Registry repository at https://github.com/KhronosGroup/EGL-Registry\n * The last semantic modification to khrplatform.h was at commit ID:\n *      67a3e0864c2d75ea5287b9f3d2eb74a745936692\n *\n * Adopters may modify this file to suit their platform. Adopters are\n * encouraged to submit platform specific modifications to the Khronos\n * group so that they can be included in future versions of this file.\n * Please submit changes by filing pull requests or issues on\n * the EGL Registry repository linked above.\n *\n *\n * See the Implementer's Guidelines for information about where this file\n * should be located on your system and for more details of its use:\n *    http://www.khronos.org/registry/implementers_guide.pdf\n *\n * This file should be included as\n *        #include <KHR/khrplatform.h>\n * by Khronos client API header files that use its types and defines.\n *\n * The types in khrplatform.h should only be used to define API-specific types.\n *\n * Types defined in khrplatform.h:\n *    khronos_int8_t              signed   8  bit\n *    khronos_uint8_t             unsigned 8  bit\n *    khronos_int16_t             signed   16 bit\n *    khronos_uint16_t            unsigned 16 bit\n *    khronos_int32_t             signed   32 bit\n *    khronos_uint32_t            unsigned 32 bit\n *    khronos_int64_t             signed   64 bit\n *    khronos_uint64_t            unsigned 64 bit\n *    khronos_intptr_t            signed   same number of bits as a pointer\n *    khronos_uintptr_t           unsigned same number of bits as a pointer\n *    khronos_ssize_t             signed   size\n *    khronos_usize_t             unsigned size\n *    khronos_float_t             signed   32 bit floating point\n *    khronos_time_ns_t           unsigned 64 bit time in nanoseconds\n *    khronos_utime_nanoseconds_t unsigned time interval or absolute time in\n *                                         nanoseconds\n *    khronos_stime_nanoseconds_t signed time interval in nanoseconds\n *    khronos_boolean_enum_t      enumerated boolean type. This should\n *      only be used as a base type when a client API's boolean type is\n *      an enum. Client APIs which use an integer or other type for\n *      booleans cannot use this as the base type for their boolean.\n *\n * Tokens defined in khrplatform.h:\n *\n *    KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.\n *\n *    KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.\n *    KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.\n *\n * Calling convention macros defined in this file:\n *    KHRONOS_APICALL\n *    KHRONOS_APIENTRY\n *    KHRONOS_APIATTRIBUTES\n *\n * These may be used in function prototypes as:\n *\n *      KHRONOS_APICALL void KHRONOS_APIENTRY funcname(\n *                                  int arg1,\n *                                  int arg2) KHRONOS_APIATTRIBUTES;\n */\n\n#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)\n#   define KHRONOS_STATIC 1\n#endif\n\n/*-------------------------------------------------------------------------\n * Definition of KHRONOS_APICALL\n *-------------------------------------------------------------------------\n * This precedes the return type of the function in the function prototype.\n */\n#if defined(KHRONOS_STATIC)\n    /* If the preprocessor constant KHRONOS_STATIC is defined, make the\n     * header compatible with static linking. */\n#   define KHRONOS_APICALL\n#elif defined(_WIN32)\n#   define KHRONOS_APICALL __declspec(dllimport)\n#elif defined (__SYMBIAN32__)\n#   define KHRONOS_APICALL IMPORT_C\n#elif defined(__ANDROID__)\n#   define KHRONOS_APICALL __attribute__((visibility(\"default\")))\n#else\n#   define KHRONOS_APICALL\n#endif\n\n/*-------------------------------------------------------------------------\n * Definition of KHRONOS_APIENTRY\n *-------------------------------------------------------------------------\n * This follows the return type of the function  and precedes the function\n * name in the function prototype.\n */\n#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)\n    /* Win32 but not WinCE */\n#   define KHRONOS_APIENTRY __stdcall\n#else\n#   define KHRONOS_APIENTRY\n#endif\n\n/*-------------------------------------------------------------------------\n * Definition of KHRONOS_APIATTRIBUTES\n *-------------------------------------------------------------------------\n * This follows the closing parenthesis of the function prototype arguments.\n */\n#if defined (__ARMCC_2__)\n#define KHRONOS_APIATTRIBUTES __softfp\n#else\n#define KHRONOS_APIATTRIBUTES\n#endif\n\n/*-------------------------------------------------------------------------\n * basic type definitions\n *-----------------------------------------------------------------------*/\n#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)\n\n\n/*\n * Using <stdint.h>\n */\n#include <stdint.h>\ntypedef int32_t                 khronos_int32_t;\ntypedef uint32_t                khronos_uint32_t;\ntypedef int64_t                 khronos_int64_t;\ntypedef uint64_t                khronos_uint64_t;\n#define KHRONOS_SUPPORT_INT64   1\n#define KHRONOS_SUPPORT_FLOAT   1\n/*\n * To support platform where unsigned long cannot be used interchangeably with\n * inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.\n * Ideally, we could just use (u)intptr_t everywhere, but this could result in\n * ABI breakage if khronos_uintptr_t is changed from unsigned long to\n * unsigned long long or similar (this results in different C++ name mangling).\n * To avoid changes for existing platforms, we restrict usage of intptr_t to\n * platforms where the size of a pointer is larger than the size of long.\n */\n#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)\n#if __SIZEOF_POINTER__ > __SIZEOF_LONG__\n#define KHRONOS_USE_INTPTR_T\n#endif\n#endif\n\n#elif defined(__VMS ) || defined(__sgi)\n\n/*\n * Using <inttypes.h>\n */\n#include <inttypes.h>\ntypedef int32_t                 khronos_int32_t;\ntypedef uint32_t                khronos_uint32_t;\ntypedef int64_t                 khronos_int64_t;\ntypedef uint64_t                khronos_uint64_t;\n#define KHRONOS_SUPPORT_INT64   1\n#define KHRONOS_SUPPORT_FLOAT   1\n\n#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)\n\n/*\n * Win32\n */\ntypedef __int32                 khronos_int32_t;\ntypedef unsigned __int32        khronos_uint32_t;\ntypedef __int64                 khronos_int64_t;\ntypedef unsigned __int64        khronos_uint64_t;\n#define KHRONOS_SUPPORT_INT64   1\n#define KHRONOS_SUPPORT_FLOAT   1\n\n#elif defined(__sun__) || defined(__digital__)\n\n/*\n * Sun or Digital\n */\ntypedef int                     khronos_int32_t;\ntypedef unsigned int            khronos_uint32_t;\n#if defined(__arch64__) || defined(_LP64)\ntypedef long int                khronos_int64_t;\ntypedef unsigned long int       khronos_uint64_t;\n#else\ntypedef long long int           khronos_int64_t;\ntypedef unsigned long long int  khronos_uint64_t;\n#endif /* __arch64__ */\n#define KHRONOS_SUPPORT_INT64   1\n#define KHRONOS_SUPPORT_FLOAT   1\n\n#elif 0\n\n/*\n * Hypothetical platform with no float or int64 support\n */\ntypedef int                     khronos_int32_t;\ntypedef unsigned int            khronos_uint32_t;\n#define KHRONOS_SUPPORT_INT64   0\n#define KHRONOS_SUPPORT_FLOAT   0\n\n#else\n\n/*\n * Generic fallback\n */\n#include <stdint.h>\ntypedef int32_t                 khronos_int32_t;\ntypedef uint32_t                khronos_uint32_t;\ntypedef int64_t                 khronos_int64_t;\ntypedef uint64_t                khronos_uint64_t;\n#define KHRONOS_SUPPORT_INT64   1\n#define KHRONOS_SUPPORT_FLOAT   1\n\n#endif\n\n\n/*\n * Types that are (so far) the same on all platforms\n */\ntypedef signed   char          khronos_int8_t;\ntypedef unsigned char          khronos_uint8_t;\ntypedef signed   short int     khronos_int16_t;\ntypedef unsigned short int     khronos_uint16_t;\n\n/*\n * Types that differ between LLP64 and LP64 architectures - in LLP64,\n * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears\n * to be the only LLP64 architecture in current use.\n */\n#ifdef KHRONOS_USE_INTPTR_T\ntypedef intptr_t               khronos_intptr_t;\ntypedef uintptr_t              khronos_uintptr_t;\n#elif defined(_WIN64)\ntypedef signed   long long int khronos_intptr_t;\ntypedef unsigned long long int khronos_uintptr_t;\n#else\ntypedef signed   long  int     khronos_intptr_t;\ntypedef unsigned long  int     khronos_uintptr_t;\n#endif\n\n#if defined(_WIN64)\ntypedef signed   long long int khronos_ssize_t;\ntypedef unsigned long long int khronos_usize_t;\n#else\ntypedef signed   long  int     khronos_ssize_t;\ntypedef unsigned long  int     khronos_usize_t;\n#endif\n\n#if KHRONOS_SUPPORT_FLOAT\n/*\n * Float type\n */\ntypedef          float         khronos_float_t;\n#endif\n\n#if KHRONOS_SUPPORT_INT64\n/* Time types\n *\n * These types can be used to represent a time interval in nanoseconds or\n * an absolute Unadjusted System Time.  Unadjusted System Time is the number\n * of nanoseconds since some arbitrary system event (e.g. since the last\n * time the system booted).  The Unadjusted System Time is an unsigned\n * 64 bit value that wraps back to 0 every 584 years.  Time intervals\n * may be either signed or unsigned.\n */\ntypedef khronos_uint64_t       khronos_utime_nanoseconds_t;\ntypedef khronos_int64_t        khronos_stime_nanoseconds_t;\n#endif\n\n/*\n * Dummy value used to pad enum types to 32 bits.\n */\n#ifndef KHRONOS_MAX_ENUM\n#define KHRONOS_MAX_ENUM 0x7FFFFFFF\n#endif\n\n/*\n * Enumerated boolean type\n *\n * Values other than zero should be considered to be true.  Therefore\n * comparisons should not be made against KHRONOS_TRUE.\n */\ntypedef enum {\n    KHRONOS_FALSE = 0,\n    KHRONOS_TRUE  = 1,\n    KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM\n} khronos_boolean_enum_t;\n\n#endif /* __khrplatform_h_ */\n"
  },
  {
    "path": "prepare_colmap_data.py",
    "content": "import argparse\nimport os\nimport warnings\n\nimport pycolmap\nfrom PIL import Image\nimport tqdm\n\n\ndef main(args):\n    \"\"\"Minimal script to run COLMAP on a directory of images.\"\"\"\n\n    data_dir = args.data_dir\n    reconstruction_dir = os.path.join(data_dir, \"sparse\")\n\n    if os.path.exists(reconstruction_dir):\n        raise ValueError(\"Reconstruction directory already exists\")\n\n    images_dir = os.path.join(data_dir, \"images\")\n    if not os.path.exists(images_dir):\n        raise ValueError(\"data_dir must contain an 'images' directory\")\n\n    database_path = os.path.join(data_dir, \"database.db\")\n    if os.path.exists(database_path):\n        raise ValueError(\"Database file already exists\")\n\n    database = pycolmap.Database(database_path)\n\n    pycolmap.extract_features(\n        database_path,\n        images_dir,\n        camera_mode=pycolmap.CameraMode.SINGLE,\n        camera_model=args.camera_model,\n    )\n\n    print(f\"Imported {database.num_images} images to {database_path}\")\n\n    pycolmap.match_exhaustive(database_path)\n\n    print(f\"Feature matching completed\")\n\n    os.makedirs(reconstruction_dir)\n\n    reconstructions = pycolmap.incremental_mapping(\n        database_path,\n        image_path=images_dir,\n        output_path=reconstruction_dir,\n    )\n\n    if len(reconstructions) > 1:\n        warnings.warn(\"Multiple reconstructions found\")\n\n    reconstruction = reconstructions[0]\n\n    os.makedirs(os.path.join(data_dir, \"images_2\"), exist_ok=True)\n    os.makedirs(os.path.join(data_dir, \"images_4\"), exist_ok=True)\n    os.makedirs(os.path.join(data_dir, \"images_8\"), exist_ok=True)\n\n    print(\"Downsampling images\")\n\n    for image in tqdm.tqdm(list(reconstruction.images.values())):\n        image_1_path = os.path.join(images_dir, image.name)\n        image_2_path = os.path.join(data_dir, \"images_2\", image.name)\n        image_4_path = os.path.join(data_dir, \"images_4\", image.name)\n        image_8_path = os.path.join(data_dir, \"images_8\", image.name)\n\n        pil_image = Image.open(image_1_path)\n        pil_image_2 = pil_image.resize(\n            (pil_image.width // 2, pil_image.height // 2),\n            resample=Image.LANCZOS,\n        )\n        pil_image_4 = pil_image.resize(\n            (pil_image.width // 4, pil_image.height // 4),\n            resample=Image.LANCZOS,\n        )\n        pil_image_8 = pil_image.resize(\n            (pil_image.width // 8, pil_image.height // 8),\n            resample=Image.LANCZOS,\n        )\n\n        pil_image_2.save(image_2_path)\n        pil_image_4.save(image_4_path)\n        pil_image_8.save(image_8_path)\n\n        pil_image.close()\n        pil_image_2.close()\n        pil_image_4.close()\n        pil_image_8.close()\n\n    print(\"Exporting point cloud\")\n\n    reconstruction.export_PLY(os.path.join(data_dir, \"point_cloud.ply\"))\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"data_dir\", type=str)\n    parser.add_argument(\"--camera_model\", type=str, default=\"OPENCV\")\n    args = parser.parse_args()\n    main(args)\n"
  },
  {
    "path": "pyproject.toml",
    "content": "[build-system]\nrequires = [\n    \"setuptools>=64\",\n    \"pybind11\",\n    \"glfw==2.6.5\",\n    \"cmake_build_extension\",\n]\nbuild-backend = \"setuptools.build_meta\"\n\n[tool.black]\nline-length = 80\n"
  },
  {
    "path": "radfoam_model/__init__.py",
    "content": ""
  },
  {
    "path": "radfoam_model/render.py",
    "content": "import torch\n\n\nclass ErrorBox:\n    def __init__(self):\n        self.ray_error = None\n        self.point_error = None\n\n\nclass TraceRays(torch.autograd.Function):\n    @staticmethod\n    def forward(\n        ctx,\n        pipeline,\n        _points,\n        _attributes,\n        _point_adjacency,\n        _point_adjacency_offsets,\n        rays,\n        start_point,\n        depth_quantiles,\n        return_contribution,\n    ):\n        ctx.rays = rays\n        ctx.start_point = start_point\n        ctx.depth_quantiles = depth_quantiles\n        ctx.pipeline = pipeline\n        ctx.points = _points\n        ctx.attributes = _attributes\n        ctx.point_adjacency = _point_adjacency\n        ctx.point_adjacency_offsets = _point_adjacency_offsets\n\n        results = pipeline.trace_forward(\n            _points,\n            _attributes,\n            _point_adjacency,\n            _point_adjacency_offsets,\n            rays,\n            start_point,\n            depth_quantiles=depth_quantiles,\n            return_contribution=return_contribution,\n        )\n        ctx.rgba = results[\"rgba\"]\n        ctx.depth_indices = results.get(\"depth_indices\", None)\n\n        errbox = ErrorBox()\n        ctx.errbox = errbox\n\n        return (\n            results[\"rgba\"],\n            results.get(\"depth\", None),\n            results.get(\"contribution\", None),\n            results[\"num_intersections\"],\n            errbox,\n        )\n\n    @staticmethod\n    def backward(\n        ctx,\n        grad_rgba,\n        grad_depth,\n        grad_contribution,\n        grad_num_intersections,\n        errbox_grad,\n    ):\n        del grad_contribution\n        del grad_num_intersections\n        del errbox_grad\n\n        rays = ctx.rays\n        start_point = ctx.start_point\n        pipeline = ctx.pipeline\n        rgba = ctx.rgba\n        _points = ctx.points\n        _attributes = ctx.attributes\n        _point_adjacency = ctx.point_adjacency\n        _point_adjacency_offsets = ctx.point_adjacency_offsets\n        depth_quantiles = ctx.depth_quantiles\n\n        results = pipeline.trace_backward(\n            _points,\n            _attributes,\n            _point_adjacency,\n            _point_adjacency_offsets,\n            rays,\n            start_point,\n            rgba,\n            grad_rgba,\n            depth_quantiles,\n            ctx.depth_indices,\n            grad_depth,\n            ctx.errbox.ray_error,\n        )\n        points_grad = results[\"points_grad\"]\n        attr_grad = results[\"attr_grad\"]\n        ctx.errbox.point_error = results.get(\"point_error\", None)\n\n        points_grad[~points_grad.isfinite()] = 0\n        attr_grad[~attr_grad.isfinite()] = 0\n\n        del (\n            ctx.rays,\n            ctx.start_point,\n            ctx.pipeline,\n            ctx.rgba,\n            ctx.points,\n            ctx.attributes,\n            ctx.point_adjacency,\n            ctx.point_adjacency_offsets,\n            ctx.depth_quantiles,\n        )\n        return (\n            None,  # pipeline\n            points_grad,  # _points\n            attr_grad,  # _attributes\n            None,  # _point_adjacency\n            None,  # _point_adjacency_offsets\n            None,  # rays\n            None,  # start_point\n            None,  # depth_quantiles\n            None,  # return_contribution\n        )\n"
  },
  {
    "path": "radfoam_model/scene.py",
    "content": "import os\nimport torch\nfrom torch import nn\nimport torch.nn.functional as F\nfrom plyfile import PlyData, PlyElement\nimport tqdm\n\nimport radfoam\nfrom radfoam_model.render import TraceRays\nfrom radfoam_model.utils import *\n\n\nclass RadFoamScene(torch.nn.Module):\n\n    def __init__(\n        self,\n        args,\n        points=None,\n        points_colors=None,\n        cameras=None,\n        device=torch.device(\"cuda\"),\n        attr_dtype=torch.float32,\n    ):\n        super().__init__()\n\n        self.device = device\n        self.attr_dtype = attr_dtype\n        if cameras is not None:\n            self.cameras = cameras.to(device)\n        else:\n            self.cameras = None\n        self.sh_degree = args.sh_degree\n        self.num_init_points = args.init_points\n        self.num_final_points = args.final_points\n        self.activation_scale = args.activation_scale\n\n        if points is not None:\n            self.initialize_from_pcd(points, points_colors)\n        else:\n            self.random_initialize()\n\n        self.att_dc = nn.Parameter(\n            torch.zeros(\n                self.num_init_points,\n                3,\n                device=self.device,\n                dtype=self.attr_dtype,\n            )\n        )\n        self.att_sh = nn.Parameter(\n            torch.zeros(\n                self.num_init_points,\n                3 * ((1 + self.sh_degree) * (1 + self.sh_degree) - 1),\n                device=device,\n                dtype=self.attr_dtype,\n            )\n        )\n\n        self.pipeline = radfoam.create_pipeline(self.sh_degree, self.attr_dtype)\n\n    def random_initialize(self):\n        primal_points = (\n            torch.randn(self.num_init_points, 3, device=self.device) * 25\n        )\n        self.triangulation = radfoam.Triangulation(primal_points)\n        perm = self.triangulation.permutation().to(torch.long)\n        primal_points = primal_points[perm]\n\n        self.primal_points = nn.Parameter(primal_points)\n        self.faces = None\n\n        self.update_triangulation(rebuild=False)\n\n        self.att_dc = nn.Parameter(\n            torch.zeros(\n                self.num_init_points,\n                3,\n                device=self.device,\n                dtype=self.attr_dtype,\n            )\n        )\n\n        density = torch.zeros(\n            self.num_init_points, 1, device=self.device, dtype=self.attr_dtype\n        )\n        self.density = nn.Parameter(density[perm])\n\n    def initialize_from_pcd(self, points, points_colors):\n        points = points.to(self.device)\n        points_colors = points_colors.to(self.device)\n\n        num_random = 5_000\n        random = torch.randn([num_random, 3], device=self.device) * 10\n\n        num_samples = int(0.9 * points.shape[0])\n        print(\n            f\"Starting with {num_samples} points from {points.shape[0]} COLMAP points\"\n        )\n        points_idx = torch.randint(0, points.shape[0], (num_samples,))\n        samp_points = points[points_idx]\n        samp_points += torch.randn_like(samp_points) * 1e-2\n        samp_colors = points_colors[points_idx]\n\n        primal_points = torch.cat([samp_points, random], dim=0)\n        primal_density = torch.cat(\n            [\n                torch.rand(samp_colors.shape[0], 1, dtype=self.attr_dtype),\n                -0.5 * torch.ones(num_random, 1, dtype=self.attr_dtype),\n            ],\n            dim=0,\n        ).to(self.device)\n\n        torch.cuda.empty_cache()\n\n        self.triangulation = radfoam.Triangulation(primal_points)\n        perm = self.triangulation.permutation().to(torch.long)\n        primal_points = primal_points[perm]\n\n        self.primal_points = nn.Parameter(primal_points)\n        self.faces = None\n\n        self.update_triangulation(rebuild=False)\n\n        self.density = nn.Parameter(primal_density)\n        self.num_init_points = self.primal_points.shape[0]\n\n    def permute_points(self, permutation):\n        optimizable_tensors = {}\n        for group in self.optimizer.param_groups:\n            if \"env\" not in group[\"name\"]:\n                stored_state = self.optimizer.state.get(\n                    group[\"params\"][0], None\n                )\n                if stored_state is not None:\n                    stored_state[\"exp_avg\"] = stored_state[\"exp_avg\"][\n                        permutation\n                    ]\n                    stored_state[\"exp_avg_sq\"] = stored_state[\"exp_avg_sq\"][\n                        permutation\n                    ]\n\n                    del self.optimizer.state[group[\"params\"][0]]\n                    group[\"params\"][0] = nn.Parameter(\n                        (group[\"params\"][0][permutation].requires_grad_(True))\n                    )\n                    self.optimizer.state[group[\"params\"][0]] = stored_state\n\n                    optimizable_tensors[group[\"name\"]] = group[\"params\"][0]\n                else:\n                    group[\"params\"][0] = nn.Parameter(\n                        group[\"params\"][0][permutation].requires_grad_(True)\n                    )\n                    optimizable_tensors[group[\"name\"]] = group[\"params\"][0]\n\n        self.primal_points = optimizable_tensors[\"primal_points\"]\n        self.density = optimizable_tensors[\"density\"]\n        self.att_dc = optimizable_tensors[\"att_dc\"]\n        self.att_sh = optimizable_tensors[\"att_sh\"]\n\n    def update_triangulation(self, rebuild=True, incremental=False):\n        if not self.primal_points.isfinite().all():\n            raise RuntimeError(\"NaN in points\")\n\n        needs_permute = False\n        perturbation = 1e-6\n        del_points = self.primal_points\n        failures = 0\n        while rebuild:\n            if failures > 25:\n                raise RuntimeError(\"aborted triangulation after 25 attempts\")\n            try:\n                needs_permute = self.triangulation.rebuild(\n                    del_points, incremental=incremental\n                )\n                break\n            except radfoam.TriangulationFailedError as e:\n                print(\"caught: \", e)\n                perturbation *= 2\n                failures += 1\n                incremental = False\n                with torch.no_grad():\n                    del_points = (\n                        self.primal_points\n                        + perturbation * torch.randn_like(self.primal_points)\n                    )\n\n        if failures > 5:\n            with torch.no_grad():\n                self.primal_points.copy_(del_points)\n\n        if needs_permute:\n            perm = self.triangulation.permutation().to(torch.long)\n            self.permute_points(perm)\n\n        self.aabb_tree = radfoam.build_aabb_tree(self.primal_points)\n\n        self.point_adjacency = self.triangulation.point_adjacency()\n        self.point_adjacency_offsets = (\n            self.triangulation.point_adjacency_offsets()\n        )\n\n    def get_primal_density(self):\n        return self.activation_scale * F.softplus(self.density, beta=10)\n\n    def get_primal_attributes(self):\n        return torch.cat([self.att_dc, self.att_sh], dim=-1)\n\n    def get_trace_data(self):\n        points = self.primal_points\n        attributes = torch.cat(\n            [self.get_primal_attributes(), self.get_primal_density()],\n            dim=-1,\n        ).to(self.attr_dtype)\n        point_adjacency = self.point_adjacency\n        point_adjacency_offsets = self.point_adjacency_offsets\n\n        return points, attributes, point_adjacency, point_adjacency_offsets\n\n    def show(self, loop_fn=lambda v: None, iterations=None, **viewer_kwargs):\n        radfoam.run_with_viewer(\n            self.pipeline, loop_fn, total_iterations=iterations, **viewer_kwargs\n        )\n\n    def get_starting_point(self, rays, points, aabb_tree):\n        with torch.no_grad():\n            camera_origins = rays[..., :3]\n            unique_cameras, inverse_indices = torch.unique(\n                camera_origins, dim=0, return_inverse=True\n            )\n\n            nn_inds = radfoam.nn(points, aabb_tree, unique_cameras).long()\n\n            start_point = nn_inds[inverse_indices]\n            return start_point.type(torch.uint32)\n\n    def forward(\n        self,\n        rays,\n        start_point=None,\n        depth_quantiles=None,\n        return_contribution=False,\n    ):\n        points, attributes, point_adjacency, point_adjacency_offsets = (\n            self.get_trace_data()\n        )\n\n        if start_point is None:\n            start_point = self.get_starting_point(rays, points, self.aabb_tree)\n        else:\n            start_point = torch.broadcast_to(start_point, rays.shape[:-1])\n        return TraceRays.apply(\n            self.pipeline,\n            points,\n            attributes,\n            point_adjacency,\n            point_adjacency_offsets,\n            rays,\n            start_point,\n            depth_quantiles,\n            return_contribution,\n        )\n\n    def update_viewer(self, viewer):\n        points, attributes, point_adjacency, point_adjacency_offsets = (\n            self.get_trace_data()\n        )\n        viewer.update_scene(\n            points,\n            attributes,\n            point_adjacency,\n            point_adjacency_offsets,\n            self.aabb_tree,\n        )\n\n    def declare_optimizer(self, args, warmup, max_iterations):\n        params = [\n            {\n                \"params\": self.primal_points,\n                \"lr\": args.points_lr_init,\n                \"name\": \"primal_points\",\n            },\n            {\n                \"params\": self.density,\n                \"lr\": args.density_lr_init,\n                \"name\": \"density\",\n            },\n            {\n                \"params\": self.att_dc,\n                \"lr\": args.attributes_lr_init,\n                \"name\": \"att_dc\",\n            },\n            {\n                \"params\": self.att_sh,\n                \"lr\": args.attributes_lr_init,\n                \"name\": \"att_sh\",\n            },\n        ]\n\n        self.optimizer = torch.optim.Adam(params, eps=1e-15)\n        self.xyz_scheduler_args = get_cosine_lr_func(\n            lr_init=args.points_lr_init,\n            lr_final=args.points_lr_final,\n            max_steps=args.freeze_points,\n        )\n        self.den_scheduler_args = get_cosine_lr_func(\n            lr_init=args.density_lr_init,\n            lr_final=args.density_lr_final,\n            warmup_steps=warmup,\n            max_steps=max_iterations,\n        )\n        self.attr_dc_scheduler_args = get_cosine_lr_func(\n            lr_init=args.attributes_lr_init,\n            lr_final=args.attributes_lr_final,\n            max_steps=max_iterations,\n        )\n        self.attr_rest_scheduler_args = get_cosine_lr_func(\n            lr_init=args.sh_factor * args.attributes_lr_init,\n            lr_final=args.sh_factor * args.attributes_lr_final,\n            warmup_steps=max_iterations // 5,\n            max_steps=max_iterations,\n        )\n\n    def update_learning_rate(self, iteration):\n        \"\"\"Learning rate scheduling per step\"\"\"\n        for param_group in self.optimizer.param_groups:\n            if param_group[\"name\"] == \"primal_points\":\n                lr = self.xyz_scheduler_args(iteration)\n                param_group[\"lr\"] = lr\n            elif param_group[\"name\"] == \"density\":\n                lr = self.den_scheduler_args(iteration)\n                param_group[\"lr\"] = lr\n                param_group[\"lr\"] = lr\n            elif param_group[\"name\"] == \"att_dc\":\n                lr = self.attr_dc_scheduler_args(iteration)\n                param_group[\"lr\"] = lr\n            elif param_group[\"name\"] == \"att_sh\":\n                lr = self.attr_rest_scheduler_args(iteration)\n                param_group[\"lr\"] = lr\n\n    def prune_optimizer(self, mask):\n        optimizable_tensors = {}\n        for group in self.optimizer.param_groups:\n            stored_state = self.optimizer.state.get(group[\"params\"][0], None)\n            if stored_state is not None:\n                stored_state[\"exp_avg\"] = stored_state[\"exp_avg\"][mask]\n                stored_state[\"exp_avg_sq\"] = stored_state[\"exp_avg_sq\"][mask]\n\n                del self.optimizer.state[group[\"params\"][0]]\n                group[\"params\"][0] = nn.Parameter(\n                    (group[\"params\"][0][mask].requires_grad_(True))\n                )\n                self.optimizer.state[group[\"params\"][0]] = stored_state\n\n                optimizable_tensors[group[\"name\"]] = group[\"params\"][0]\n            else:\n                group[\"params\"][0] = nn.Parameter(\n                    group[\"params\"][0][mask].requires_grad_(True)\n                )\n                optimizable_tensors[group[\"name\"]] = group[\"params\"][0]\n        return optimizable_tensors\n\n    def prune_points(self, prune_mask):\n        valid_points_mask = ~prune_mask\n        optimizable_tensors = self.prune_optimizer(valid_points_mask)\n        self.primal_points = optimizable_tensors[\"primal_points\"]\n        self.att_dc = optimizable_tensors[\"att_dc\"]\n        self.att_sh = optimizable_tensors[\"att_sh\"]\n        self.density = optimizable_tensors[\"density\"]\n\n    def cat_tensors_to_optimizer(self, new_params):\n        optimizable_tensors = {}\n        for group in self.optimizer.param_groups:\n            if group[\"name\"] in new_params.keys():\n                assert len(group[\"params\"]) == 1\n                stored_tensor = group[\"params\"][0]\n                extension_tensor = new_params[group[\"name\"]]\n                stored_state = self.optimizer.state.get(\n                    group[\"params\"][0], None\n                )\n                if stored_state is not None:\n                    stored_state[\"exp_avg\"] = torch.cat(\n                        (\n                            stored_state[\"exp_avg\"],\n                            torch.zeros_like(extension_tensor),\n                        ),\n                        dim=0,\n                    )\n                    stored_state[\"exp_avg_sq\"] = torch.cat(\n                        (\n                            stored_state[\"exp_avg_sq\"],\n                            torch.zeros_like(extension_tensor),\n                        ),\n                        dim=0,\n                    )\n\n                    del self.optimizer.state[group[\"params\"][0]]\n                    group[\"params\"][0] = nn.Parameter(\n                        torch.cat(\n                            (stored_tensor, extension_tensor), dim=0\n                        ).requires_grad_(True)\n                    )\n                    self.optimizer.state[group[\"params\"][0]] = stored_state\n\n                    optimizable_tensors[group[\"name\"]] = group[\"params\"][0]\n                else:\n                    group[\"params\"][0] = nn.Parameter(\n                        torch.cat(\n                            (stored_tensor, extension_tensor), dim=0\n                        ).requires_grad_(True)\n                    )\n                    optimizable_tensors[group[\"name\"]] = group[\"params\"][0]\n\n        return optimizable_tensors\n\n    def densification_postfix(self, new_params):\n        optimizable_tensors = self.cat_tensors_to_optimizer(new_params)\n        self.primal_points = optimizable_tensors[\"primal_points\"]\n        self.att_dc = optimizable_tensors[\"att_dc\"]\n        self.att_sh = optimizable_tensors[\"att_sh\"]\n        self.density = optimizable_tensors[\"density\"]\n\n    def prune_and_densify(\n        self, point_error, point_contribution, upsample_factor=1.2\n    ):\n        with torch.no_grad():\n            num_curr_points = self.primal_points.shape[0]\n            num_new_points = int((upsample_factor - 1) * num_curr_points)\n\n            primal_error_accum = point_error.clip(min=0).squeeze()\n            points, _, point_adjacency, point_adjacency_offsets = (\n                self.get_trace_data()\n            )\n            ################### Farthest neighbor ###################\n            farthest_neighbor, cell_radius = radfoam.farthest_neighbor(\n                points,\n                point_adjacency,\n                point_adjacency_offsets,\n            )\n            farthest_neighbor = farthest_neighbor.long()\n\n            ######################## Pruning ########################\n            self_mask = point_contribution > 1e-2\n            neighbor_mask = self_mask.long()[point_adjacency.long()]\n            neighbor_mask = torch.cat(\n                [neighbor_mask, torch.zeros_like(neighbor_mask[:1])], dim=0\n            )\n            nsum = torch.cumsum(neighbor_mask, dim=0)\n\n            offsets = point_adjacency_offsets.long()\n            n_masked_adj = nsum[offsets[1:]] - nsum[offsets[:-1]]\n\n            contrib_mask = ((n_masked_adj == 0) & ~self_mask).squeeze()\n            cell_size_mask = cell_radius < 1e-1\n            prune_mask = contrib_mask * cell_size_mask\n\n            ######################## Random sampling ########################\n            primal_contribution_accum = point_contribution.squeeze()\n            mask = primal_contribution_accum < 1e-3\n            self.density[mask] = -1\n\n            perturbation = 0.25 * (points[farthest_neighbor] - points)\n            delta = torch.randn_like(perturbation)\n            delta /= delta.norm(dim=-1, keepdim=True)\n            perturbation += (\n                0.1 * perturbation.norm(dim=-1, keepdim=True) * delta\n            )\n\n            num_sample_points = num_new_points\n            sampled_inds = torch.multinomial(\n                primal_error_accum * cell_radius,\n                num_sample_points,\n                replacement=False,\n            )\n            sampled_points = (points + perturbation)[sampled_inds]\n\n            new_params = {\n                \"primal_points\": sampled_points,\n                \"att_dc\": self.att_dc[sampled_inds],\n                \"att_sh\": self.att_sh[sampled_inds],\n                \"density\": self.density[sampled_inds],\n            }\n\n            prune_mask = torch.cat(\n                (\n                    prune_mask,\n                    torch.zeros(\n                        sampled_points.shape[0],\n                        device=prune_mask.device,\n                        dtype=bool,\n                    ),\n                )\n            )\n\n            self.densification_postfix(new_params)\n            self.prune_points(prune_mask)\n\n    def collect_error_map(self, data_handler, white_bkg=True, downsample=2):\n        rays, rgbs = data_handler.rays, data_handler.rgbs\n\n        points, _, _, _ = self.get_trace_data()\n        start_points = self.get_starting_point(\n            rays[:, 0, 0].cuda(), points, self.aabb_tree\n        )\n\n        ray_batch_fetcher = radfoam.BatchFetcher(\n            rays, batch_size=1, shuffle=False\n        )\n        rgb_batch_fetcher = radfoam.BatchFetcher(\n            rgbs, batch_size=1, shuffle=False\n        )\n\n        point_error_accum = torch.zeros_like(self.primal_points[..., 0:1])\n        point_contribution_accum = torch.zeros_like(\n            self.primal_points[..., 0:1]\n        )\n        rgb_loss = nn.L1Loss(reduction=\"none\")\n\n        for i in range(rays.shape[0]):\n            ray_batch = ray_batch_fetcher.next()\n            rgb_batch = rgb_batch_fetcher.next()\n\n            d = torch.randint(0, downsample, (2,))\n            ray_batch = ray_batch[:, d[0] :: downsample, d[1] :: downsample, :]\n            rgb_batch = rgb_batch[:, d[0] :: downsample, d[1] :: downsample, :]\n\n            rgba_output, _, contribution, _, errbox = self.forward(\n                ray_batch, start_points[i], return_contribution=True\n            )\n            opacity = rgba_output[..., -1:]\n            if white_bkg:\n                rgb_output = rgba_output[..., :3] + (1 - opacity)\n            else:\n                rgb_output = rgba_output[..., :3]\n\n            color_loss = rgb_loss(rgb_batch, rgb_output).mean(dim=-1)\n\n            color_loss.sum().backward()\n            point_error_accum += self.primal_points.grad.norm(\n                dim=-1, keepdim=True\n            ).detach()\n            point_contribution_accum = torch.maximum(\n                point_contribution_accum, contribution.detach()\n            )\n            torch.cuda.synchronize()\n\n            self.optimizer.zero_grad(set_to_none=True)\n\n        return point_error_accum, point_contribution_accum\n\n    def save_ply(self, ply_path):\n        points = self.primal_points.detach().float().cpu().numpy()\n        density = self.get_primal_density().detach().float().cpu().numpy()\n        color_attributes = (\n            self.get_primal_attributes().detach().float().cpu().numpy()\n        )\n        adjacency = self.point_adjacency.cpu().numpy()\n        adjacency_offsets = self.point_adjacency_offsets.cpu().numpy()\n\n        C0 = 0.28209479177387814\n        r = np.array(\n            np.clip(255 * (0.5 + C0 * color_attributes[:, 0]), 0, 255),\n            dtype=np.uint8,\n        )\n        g = np.array(\n            np.clip(255 * (0.5 + C0 * color_attributes[:, 1]), 0, 255),\n            dtype=np.uint8,\n        )\n        b = np.array(\n            np.clip(255 * (0.5 + C0 * color_attributes[:, 2]), 0, 255),\n            dtype=np.uint8,\n        )\n\n        vertex_data = []\n        for i in tqdm.trange(points.shape[0]):\n            vertex_data.append(\n                (\n                    points[i, 0],\n                    points[i, 1],\n                    points[i, 2],\n                    r[i],\n                    g[i],\n                    b[i],\n                    density[i, 0],\n                    adjacency_offsets[i + 1],\n                    *[\n                        color_attributes[i, 3 + j]\n                        for j in range(color_attributes.shape[1] - 3)\n                    ],\n                )\n            )\n\n        dtype = [\n            (\"x\", np.float32),\n            (\"y\", np.float32),\n            (\"z\", np.float32),\n            (\"red\", np.uint8),\n            (\"green\", np.uint8),\n            (\"blue\", np.uint8),\n            (\"density\", np.float32),\n            (\"adjacency_offset\", np.uint32),\n        ]\n\n        for i in range(self.att_sh.shape[1]):\n            dtype.append((\"color_sh_{}\".format(i), np.float32))\n\n        vertex_data = np.array(vertex_data, dtype=dtype)\n        vertex_element = PlyElement.describe(vertex_data, \"vertex\")\n\n        adjacency_data = np.array(adjacency, dtype=[(\"adjacency\", np.uint32)])\n        adjacency_element = PlyElement.describe(adjacency_data, \"adjacency\")\n\n        PlyData([vertex_element, adjacency_element]).write(ply_path)\n\n    def save_pt(self, pt_path):\n        points = self.primal_points.detach().float().cpu()\n        density = self.density.detach().float().cpu()\n        color_dc = self.att_dc.detach().float().cpu()\n        color_sh = self.att_sh.detach().float().cpu()\n        adjacency = self.point_adjacency.cpu()\n        adjacency_offsets = self.point_adjacency_offsets.cpu()\n\n        scene_data = {\n            \"xyz\": points,\n            \"density\": density,\n            \"color_dc\": color_dc,\n            \"color_sh\": color_sh,\n            \"adjacency\": adjacency.long(),\n            \"adjacency_offsets\": adjacency_offsets.long(),\n        }\n        torch.save(scene_data, pt_path)\n\n    def load_pt(self, pt_path):\n        scene_data = torch.load(pt_path)\n\n        self.primal_points = nn.Parameter(scene_data[\"xyz\"].to(self.device))\n        self.density = nn.Parameter(scene_data[\"density\"].to(self.device))\n        self.att_dc = nn.Parameter(\n            scene_data[\"color_dc\"].to(self.attr_dtype).to(self.device)\n        )\n\n        exp_sh_coeffs = 3 * ((1 + self.sh_degree) * (1 + self.sh_degree) - 1)\n        got_sh_coeffs = scene_data[\"color_sh\"].shape[-1]\n        assert (\n            exp_sh_coeffs == got_sh_coeffs\n        ), f\"Expected {exp_sh_coeffs} SH coeffs per-point, got {got_sh_coeffs}\"\n        self.att_sh = nn.Parameter(\n            scene_data[\"color_sh\"].to(self.attr_dtype).to(self.device)\n        )\n\n        self.point_adjacency = scene_data[\"adjacency\"].to(self.device).to(\n            torch.uint32)\n        self.point_adjacency_offsets = scene_data[\"adjacency_offsets\"].to(\n            self.device\n        ).to(torch.uint32)\n\n        self.aabb_tree = radfoam.build_aabb_tree(self.primal_points)\n"
  },
  {
    "path": "radfoam_model/utils.py",
    "content": "import numpy as np\nimport torch\n\n\ndef inverse_softplus(x, beta, scale=1):\n    # log(exp(scale*x)-1)/scale\n    out = x / scale\n    mask = x * beta < 20 * scale\n    out[mask] = torch.log(torch.exp(beta * out[mask]) - 1 + 1e-10) / beta\n    return out\n\n\ndef psnr(img1, img2):\n    mse = (((img1 - img2)) ** 2).view(-1, img1.shape[-1]).mean(0, keepdim=True)\n    return 20 * torch.log10(1.0 / torch.sqrt(mse))\n\n\ndef get_expon_lr_func(\n    lr_init,\n    lr_final,\n    warmup_steps=0,\n    max_steps=1_000,\n):\n    \"\"\"\n    Copied from Plenoxels\n\n    Continuous learning rate decay function. Adapted from JaxNeRF\n    The returned rate is lr_init when step=0 and lr_final when step=max_steps, and\n    is log-linearly interpolated elsewhere (equivalent to exponential decay).\n    If lr_delay_steps>0 then the learning rate will be scaled by some smooth\n    function of lr_delay_mult, such that the initial learning rate is\n    lr_init*lr_delay_mult at the beginning of optimization but will be eased back\n    to the normal learning rate when steps>lr_delay_steps.\n    :param conf: config subtree 'lr' or similar\n    :param max_steps: int, the number of steps during optimization.\n    :return HoF which takes step as input\n    \"\"\"\n\n    def helper(step):\n        if warmup_steps and step < warmup_steps:\n            return lr_init * step / warmup_steps\n        elif step > max_steps:\n            return 0\n        t = np.clip((step - warmup_steps) / (max_steps - warmup_steps), 0, 1)\n        log_lerp = np.exp(np.log(lr_init) * (1 - t) + np.log(lr_final) * t)\n        return log_lerp\n\n    return helper\n\n\ndef get_cosine_lr_func(\n    lr_init,\n    lr_final,\n    warmup_steps=0,\n    max_steps=10_000,\n):\n    \"\"\"\n    Copied from Plenoxels\n\n    Continuous learning rate decay function. Adapted from JaxNeRF\n    The returned rate is lr_init when step=0 and lr_final when step=max_steps, and\n    is log-linearly interpolated elsewhere (equivalent to exponential decay).\n    If lr_delay_steps>0 then the learning rate will be scaled by some smooth\n    function of lr_delay_mult, such that the initial learning rate is\n    lr_init*lr_delay_mult at the beginning of optimization but will be eased back\n    to the normal learning rate when steps>lr_delay_steps.\n    :param conf: config subtree 'lr' or similar\n    :param max_steps: int, the number of steps during optimization.\n    :return HoF which takes step as input\n    \"\"\"\n\n    def helper(step):\n        if warmup_steps and step < warmup_steps:\n            return lr_init * step / warmup_steps\n        elif step > max_steps:\n            return 0.0\n        lr_cos = lr_final + 0.5 * (lr_init - lr_final) * (\n            1\n            + np.cos(np.pi * (step - warmup_steps) / (max_steps - warmup_steps))\n        )\n        return lr_cos\n\n    return helper\n"
  },
  {
    "path": "requirements.txt",
    "content": "cmake==3.29.2\ncmake-format==0.6.13\ncmake_build_extension==0.6.1\nConfigArgParse==1.7\neinops==0.8.1\nglfw==2.6.5\npycolmap==3.11.1\nopencv-python==4.11.0.86\npillow==11.0.0\nplyfile==1.0.3\npybind11[global]==2.13.6\npyyaml==6.0.2\nscipy==1.15.1\ntensorboard==2.19.0\ntqdm==4.67.1"
  },
  {
    "path": "scripts/cmake_clean.sh",
    "content": "#! /bin/sh\n\ncmake-format -i CMakeLists.txt\ncmake-format -i src/CMakeLists.txt\ncmake-format -i external/CMakeLists.txt\ncmake-format -i torch_bindings/CMakeLists.txt\n"
  },
  {
    "path": "scripts/torch_info.py",
    "content": "import sys\nimport sysconfig\nimport importlib.util\n\nlib_path = sysconfig.get_path(\"purelib\")\n\ndef import_module_from_path(module_name, file_path):\n    spec = importlib.util.spec_from_file_location(module_name, file_path)\n    module = importlib.util.module_from_spec(spec)\n    spec.loader.exec_module(module)\n    return module\n\nfile_path = f\"{lib_path}/torch/version.py\"\nmodule = import_module_from_path(\"version\", file_path)\n\nif sys.argv[1] == \"torch\":\n    print(module.__version__.split(\"+\")[0])\nelif sys.argv[1] == \"cuda\":\n    print(module.cuda)\n"
  },
  {
    "path": "setup.cfg",
    "content": "[metadata]\nname = radfoam\ndescription = C++ backend for RadFoam\nlong_description = file: README.md\nlong_description_content_type = text/markdown\nauthor = Daniel Rebain\nauthor_email = drebain@cs.ubc.ca\nlicense = Apache-2.0\nplatforms = any\nurl = https://radfoam.github.io\nproject_urls =\n    Source  = https://github.com/theialab/radfoam\nkeywords = ray tracing radiance field\nclassifiers =\n\n[options]\nzip_safe = False\npackages = find:\npackage_dir =\n    =src\npython_requires = >=3.8\n\n[options.packages.find]\nwhere = src\n"
  },
  {
    "path": "setup.py",
    "content": "import os\nimport re\nimport sys\nfrom pathlib import Path\n\nimport cmake_build_extension\nimport setuptools\nimport sysconfig\nimport subprocess\n\nlib_path = sysconfig.get_path(\"purelib\")\nassert os.path.exists(\n    f\"{lib_path}/torch\"\n), \"Could not find PyTorch; please make sure it is installed in your environment before installing radfoam.\"\n\ncmake_options = []\n\nif \"CUDA_HOME\" in os.environ:\n    cmake_options.append(f\"-DCUDA_TOOLKIT_ROOT_DIR={os.environ['CUDA_HOME']}\")\n\nsource_dir = Path(__file__).parent.absolute()\ncmake = (source_dir / \"CMakeLists.txt\").read_text()\nversion = re.search(r\"project\\(\\S+ VERSION (\\S+)\\)\", cmake).group(1)\n\ninstall_requirements = [\n    \"cmake==3.29.2\",\n    \"cmake-format\",\n    \"cmake_build_extension\",\n    \"ConfigArgParse\",\n    \"einops\",\n    \"glfw==2.6.5\",\n    \"pycolmap\",\n    \"opencv-python\",\n    \"pillow\",\n    \"plyfile\",\n    \"pybind11[global]\",\n    \"pyyaml\",\n    \"scipy\",\n    \"tensorboard\",\n    \"tqdm\",\n]\n\n\nsetuptools.setup(\n    version=version,\n    install_requires=install_requirements,\n    ext_modules=[\n        cmake_build_extension.CMakeExtension(\n            name=\"RadFoamBindings\",\n            install_prefix=\"radfoam\",\n            cmake_depends_on=[\"pybind11\"],\n            write_top_level_init=None,\n            source_dir=str(source_dir),\n            cmake_configure_options=[\n                f\"-DPython3_ROOT_DIR={Path(sys.prefix)}\",\n                \"-DCALL_FROM_SETUP_PY:BOOL=ON\",\n                \"-DBUILD_SHARED_LIBS:BOOL=OFF\",\n                \"-DGPU_DEBUG:BOOL=OFF\",\n                \"-DEXAMPLE_WITH_PYBIND11:BOOL=ON\",\n                f\"-DTorch_DIR={lib_path}/torch/share/cmake/Torch\",\n                \"-DPIP_GLFW:BOOL=ON\",\n            ]\n            + cmake_options,\n        ),\n    ],\n    cmdclass=dict(\n        build_ext=cmake_build_extension.BuildExtension,\n    ),\n)\n"
  },
  {
    "path": "src/CMakeLists.txt",
    "content": "find_package(CUDAToolkit REQUIRED)\n\nadd_definitions(-D_GLIBCXX_USE_CXX11_ABI=0 -D_USE_MATH_DEFINES)\n\nlist(\n  APPEND\n  RADFOAM_INCLUDES\n  ${CMAKE_SOURCE_DIR}/external/submodules/termcolor/include\n  ${CMAKE_SOURCE_DIR}/external/submodules/eigen\n  ${CMAKE_SOURCE_DIR}/external/submodules/atomic_queue/include\n  ${GLFW_INCLUDES})\n\nlist(APPEND RADFOAM_CXX_SOURCES viewer/viewer.cpp utils/batch_fetcher.cpp)\nlist(\n  APPEND\n  RADFOAM_CUDA_SOURCES\n  aabb_tree/aabb_tree.cu\n  delaunay/delaunay.cu\n  delaunay/sample_initial_tets.cu\n  delaunay/growth_iteration.cu\n  delaunay/delete_violations.cu\n  delaunay/triangulation_ops.cu\n  tracing/pipeline.cu)\n\nadd_library(radfoam STATIC ${RADFOAM_CXX_SOURCES} ${RADFOAM_CUDA_SOURCES})\ntarget_include_directories(radfoam PUBLIC ${RADFOAM_INCLUDES})\ntarget_link_libraries(\n  radfoam PUBLIC CUDA::cudart CUDA::cuda_driver ${GLFW_LIBRARY} gl3w imgui TBB::tbb)\ntarget_compile_options(radfoam PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:-lineinfo -O3\n                                       -Wall -Wno-unknown-pragmas> -O3)\n"
  },
  {
    "path": "src/aabb_tree/aabb_tree.cu",
    "content": "#include <iostream>\n#include <vector>\n\n#include <cub/device/device_radix_sort.cuh>\n#include <cub/device/device_segmented_radix_sort.cuh>\n#include <cub/iterator/counting_input_iterator.cuh>\n#include <cub/iterator/transform_input_iterator.cuh>\n\n#include \"../utils/cuda_helpers.h\"\n\n#include \"../utils/common_kernels.cuh\"\n#include \"aabb_tree.cuh\"\n\n#define BUILD_AABB_BLOCK_SIZE 256\n#define SORT_BLOCK_SIZE 1024\n#define VORONOI_BLOCK_SIZE 256\n\nnamespace radfoam {\n\nstruct SortValue {\n    CVec3<int32_t> point;\n    uint32_t perm;\n};\n\ntemplate <int block_size>\n__global__ void block_sort_kernel(const uint32_t *__restrict__ keys_in,\n                                  uint32_t *__restrict__ keys_out,\n                                  const SortValue *__restrict__ values_in,\n                                  SortValue *__restrict__ values_out,\n                                  uint32_t num_points) {\n    typedef cub::BlockRadixSort<uint32_t, block_size, 1, SortValue> Sorter;\n    __shared__ typename Sorter::TempStorage temp_storage;\n\n    uint32_t block_offset = blockIdx.x * block_size;\n    uint32_t block_end = min(block_offset + block_size, num_points);\n\n    uint32_t key[1] = {0xffffffff};\n    SortValue perm[1];\n    if (threadIdx.x + block_offset < num_points) {\n        key[0] = keys_in[threadIdx.x + block_offset];\n        perm[0] = values_in[threadIdx.x + block_offset];\n    }\n\n    Sorter(temp_storage).Sort(key, perm);\n\n    if (threadIdx.x + block_offset < num_points) {\n        keys_out[threadIdx.x + block_offset] = key[0];\n        values_out[threadIdx.x + block_offset] = perm[0];\n    }\n}\n\nvoid launch_block_sort_kernel(const uint32_t *keys_in,\n                              uint32_t *keys_out,\n                              const SortValue *values_in,\n                              SortValue *values_out,\n                              uint32_t num_points) {\n    uint32_t num_blocks = (num_points + SORT_BLOCK_SIZE - 1) / SORT_BLOCK_SIZE;\n    block_sort_kernel<SORT_BLOCK_SIZE><<<num_blocks, SORT_BLOCK_SIZE>>>(\n        keys_in, keys_out, values_in, values_out, num_points);\n}\n\nvoid sort_points(CUDAArray<Vec3f> &points_buffer,\n                 uint32_t num_points,\n                 CUDAArray<uint32_t> &permutation) {\n\n    CUDAArray<uint32_t> keys_in_buffer(num_points);\n    CUDAArray<uint32_t> keys_out_buffer(num_points);\n    CUDAArray<SortValue> values_in_buffer(num_points);\n    CUDAArray<SortValue> values_out_buffer(num_points);\n\n    uint32_t *keys_in = keys_in_buffer.begin();\n    uint32_t *keys_out = keys_out_buffer.begin();\n    SortValue *values_in = values_in_buffer.begin();\n    SortValue *values_out = values_out_buffer.begin();\n\n    auto points_begin = points_buffer.begin();\n\n    transform_range(u32zero(),\n                    u32zero() + num_points,\n                    values_in,\n                    [=] __device__(uint32_t i) {\n                        Vec3f p = points_begin[i];\n                        SortValue value;\n\n                        for (int j = 0; j < 3; ++j) {\n                            uint32_t u;\n                            memcpy(&u, &p[j], sizeof(uint32_t));\n\n                            if (u & 0x80000000) {\n                                u = ~u;\n                            } else {\n                                u ^= 0x80000000;\n                            }\n                            value.point.data[j] = (int32_t)u;\n                        }\n                        value.perm = i;\n                        return value;\n                    });\n\n    uint32_t segment_size = pow2_round_up(num_points);\n    int dim = 0;\n\n    while (segment_size > 1) {\n        uint32_t num_segments = (num_points + segment_size - 1) / segment_size;\n\n        if (segment_size > SORT_BLOCK_SIZE) {\n            if (num_segments > 1024) {\n                // CUB segmented sort\n                for_n(u32zero(), num_points, [=] __device__(uint32_t i) {\n                    keys_in[i] = values_in[i].point.data[dim];\n                });\n\n                auto get_segment_offset = [=] __device__(const uint32_t &i) {\n                    return min(i * segment_size, num_points);\n                };\n\n                auto segment_offset_begin =\n                    cub::TransformInputIterator<uint32_t,\n                                                decltype(get_segment_offset),\n                                                decltype(u32zero())>(\n                        u32zero(), get_segment_offset);\n\n                CUB_CALL(cub::DeviceSegmentedRadixSort::SortPairs(\n                    temp_data,\n                    temp_bytes,\n                    keys_in,\n                    keys_out,\n                    values_in,\n                    values_out,\n                    num_points,\n                    num_segments,\n                    segment_offset_begin,\n                    segment_offset_begin + 1));\n            } else {\n                // CUB global sort\n                uint32_t segment_bits = log2(pow2_round_up(num_segments));\n\n                for_n(u32zero(), num_points, [=] __device__(uint32_t i) {\n                    keys_in[i] = values_in[i].point.data[dim];\n                });\n\n                CUB_CALL(cub::DeviceRadixSort::SortPairs(temp_data,\n                                                         temp_bytes,\n                                                         keys_in,\n                                                         keys_out,\n                                                         values_in,\n                                                         values_out,\n                                                         num_points));\n            }\n\n        } else {\n            // Block sort\n            uint32_t segment_bits = log2(SORT_BLOCK_SIZE) - log2(segment_size);\n\n            for_n(u32zero(), num_points, [=] __device__(uint32_t i) {\n                keys_in[i] = values_in[i].point.data[dim];\n            });\n\n            launch_block_sort_kernel(\n                keys_in, keys_out, values_in, values_out, num_points);\n        }\n\n        segment_size >>= 1;\n        dim = (dim + 1) % 3;\n\n        std::swap(values_in, values_out);\n    }\n\n    permutation.expand(num_points);\n\n    uint32_t *permutation_begin = permutation.begin();\n    for_n(u32zero(), num_points, [=] __device__(uint32_t i) {\n        Vec3f p;\n\n        for (int j = 0; j < 3; ++j) {\n            uint32_t u = (uint32_t)values_in[i].point.data[j];\n\n            if (u & 0x80000000) {\n                u ^= 0x80000000;\n            } else {\n                u = ~u;\n            }\n\n            memcpy(&p[j], &u, sizeof(float));\n        }\n\n        points_begin[i] = p;\n        permutation_begin[i] = values_in[i].perm;\n    });\n}\n\ntemplate <typename scalar>\n__global__ void build_leaves_kernel(const Vec3<scalar> *__restrict__ points,\n                                    uint32_t num_points,\n                                    AABB<scalar> *__restrict__ aabb_tree) {\n\n    uint32_t thread_idx = blockIdx.x * blockDim.x + threadIdx.x;\n    uint32_t point_idx = thread_idx * 2;\n    uint32_t num_leaves = pow2_round_up(num_points) / 2;\n\n    if (thread_idx >= num_leaves) {\n        return;\n    }\n\n    Vec3<scalar> leaf0;\n    if (point_idx < num_points) {\n        leaf0 = points[point_idx];\n    } else {\n        leaf0 = points[num_points - 1];\n    }\n    Vec3<scalar> leaf1;\n    if (point_idx + 1 < num_points) {\n        leaf1 = points[point_idx + 1];\n    } else {\n        leaf1 = leaf0;\n    }\n    Vec3<scalar> min_p = leaf0.cwiseMin(leaf1);\n    Vec3<scalar> max_p = leaf0.cwiseMax(leaf1);\n    AABB<scalar> leaf_aabb(min_p, max_p);\n\n    aabb_tree[thread_idx] = leaf_aabb;\n\n    uint32_t max_level = log2(min(num_leaves, BUILD_AABB_BLOCK_SIZE));\n    AABB<scalar> *prev_level_begin = aabb_tree;\n    AABB<scalar> *next_level_begin = aabb_tree + num_leaves;\n\n    uint32_t thread_idx_in_block = threadIdx.x;\n\n    for (uint32_t i = 0; i < max_level; ++i) {\n        if (thread_idx_in_block >=\n            (min(num_leaves, BUILD_AABB_BLOCK_SIZE) >> (i + 1))) {\n            return;\n        }\n        uint32_t prev_level_idx =\n            blockIdx.x * (blockDim.x >> i) + thread_idx_in_block * 2;\n        uint32_t next_level_idx =\n            blockIdx.x * (blockDim.x >> (i + 1)) + thread_idx_in_block;\n\n        __syncthreads();\n\n        AABB<scalar> prev_0 = prev_level_begin[prev_level_idx];\n        AABB<scalar> prev_1 = prev_level_begin[prev_level_idx + 1];\n\n        AABB<scalar> next = prev_0.merge(prev_1);\n\n        next_level_begin[next_level_idx] = next;\n\n        uint64_t next_level_width = (next_level_begin - prev_level_begin) >> 1;\n        prev_level_begin = next_level_begin;\n        next_level_begin += next_level_width;\n    }\n}\n\ntemplate <typename scalar>\n__global__ void build_tree_kernel(AABB<scalar> *__restrict__ start_level,\n                                  uint32_t width) {\n\n    uint32_t thread_idx = blockIdx.x * blockDim.x + threadIdx.x;\n    if (thread_idx >= width / 2) {\n        return;\n    }\n\n    uint32_t max_level = log2(min(width, BUILD_AABB_BLOCK_SIZE));\n    AABB<scalar> *prev_level_begin = start_level;\n    AABB<scalar> *next_level_begin = start_level + width;\n\n    uint32_t thread_idx_in_block = threadIdx.x;\n\n    for (uint32_t i = 0; i < max_level; ++i) {\n        if (thread_idx_in_block >=\n            (min(width / 2, BUILD_AABB_BLOCK_SIZE) >> i)) {\n            return;\n        }\n        uint32_t prev_level_idx =\n            blockIdx.x * 2 * (blockDim.x >> i) + thread_idx_in_block * 2;\n        uint32_t next_level_idx =\n            blockIdx.x * 2 * (blockDim.x >> (i + 1)) + thread_idx_in_block;\n\n        __syncthreads();\n\n        AABB<scalar> prev_0 = prev_level_begin[prev_level_idx];\n        AABB<scalar> prev_1 = prev_level_begin[prev_level_idx + 1];\n\n        AABB<scalar> next = prev_0.merge(prev_1);\n\n        next_level_begin[next_level_idx] = next;\n\n        uint64_t next_level_width = (next_level_begin - prev_level_begin) >> 1;\n        prev_level_begin = next_level_begin;\n        next_level_begin += next_level_width;\n    }\n}\n\ntemplate <typename scalar>\nvoid build_aabb_tree(const Vec3<scalar> *points,\n                     uint32_t num_points,\n                     AABB<scalar> *aabb_tree) {\n\n    uint32_t num_leaves = pow2_round_up(num_points) / 2;\n\n    uint32_t num_blocks =\n        (num_leaves + BUILD_AABB_BLOCK_SIZE - 1) / BUILD_AABB_BLOCK_SIZE;\n\n    build_leaves_kernel<<<num_blocks, BUILD_AABB_BLOCK_SIZE>>>(\n        points, num_points, aabb_tree);\n\n    uint32_t width = num_leaves / BUILD_AABB_BLOCK_SIZE;\n    AABB<scalar> *level_start = aabb_tree;\n    level_start +=\n        2 * (BUILD_AABB_BLOCK_SIZE - 1) * (num_leaves / BUILD_AABB_BLOCK_SIZE);\n\n    while (width > 1) {\n        uint32_t num_blocks =\n            (width / 2 + BUILD_AABB_BLOCK_SIZE - 1) / BUILD_AABB_BLOCK_SIZE;\n        build_tree_kernel<<<num_blocks, BUILD_AABB_BLOCK_SIZE>>>(level_start,\n                                                                 width);\n\n        for (uint32_t i = 0; i < log2(BUILD_AABB_BLOCK_SIZE); ++i) {\n            level_start += width;\n            width /= 2;\n        }\n    }\n}\n\nvoid build_aabb_tree(ScalarType scalar_type,\n                     const void *points,\n                     uint32_t num_points,\n                     void *aabb_tree) {\n\n    if (scalar_type == ScalarType::Int32) {\n        build_aabb_tree(static_cast<const Vec3<int32_t> *>(points),\n                        num_points,\n                        static_cast<AABB<int32_t> *>(aabb_tree));\n    } else if (scalar_type == ScalarType::Float32) {\n        build_aabb_tree(static_cast<const Vec3<float> *>(points),\n                        num_points,\n                        static_cast<AABB<float> *>(aabb_tree));\n    } else {\n        throw std::runtime_error(\"unsupported scalar type\");\n    }\n}\n\ntemplate <typename coord_scalar>\n__global__ void nn_kernel(const Vec3<coord_scalar> *__restrict__ points,\n                          const AABB<coord_scalar> *__restrict__ aabb_tree,\n                          const Vec3<coord_scalar> *__restrict__ queries,\n                          uint32_t num_points,\n                          uint32_t num_queries,\n                          uint32_t *__restrict__ indices) {\n    uint32_t i = (blockIdx.x * blockDim.x + threadIdx.x) / 32;\n    uint32_t lane = threadIdx.x % 32;\n\n    if (i >= num_queries) {\n        return;\n    }\n\n    Vec3<coord_scalar> query_point = queries[i];\n\n    coord_scalar dist;\n    uint32_t index;\n\n    warp_knn<VORONOI_BLOCK_SIZE>(\n        points, aabb_tree, num_points, query_point, 1, &dist, &index);\n\n    if (lane != 0) {\n        return;\n    }\n\n    indices[i] = index;\n}\n\ntemplate <typename coord_scalar>\nvoid nn(const Vec3<coord_scalar> *points,\n        const AABB<coord_scalar> *aabb_tree,\n        const Vec3<coord_scalar> *queries,\n        uint32_t num_points,\n        uint32_t num_queries,\n        uint32_t *indices,\n        const void *stream) {\n    launch_kernel_1d<VORONOI_BLOCK_SIZE>(nn_kernel<coord_scalar>,\n                                         32 * num_queries,\n                                         stream,\n                                         points,\n                                         aabb_tree,\n                                         queries,\n                                         num_points,\n                                         num_queries,\n                                         indices);\n}\n\nvoid nn(ScalarType coord_scalar_type,\n        const void *points,\n        const void *aabb_tree,\n        const void *queries,\n        uint32_t num_points,\n        uint32_t num_queries,\n        uint32_t *indices,\n        const void *stream) {\n\n    if (num_points < 32) {\n        throw std::runtime_error(\"number of points must be at least 32\");\n    }\n\n    if (coord_scalar_type == ScalarType::Float32) {\n        nn(static_cast<const Vec3<float> *>(points),\n           static_cast<const AABB<float> *>(aabb_tree),\n           static_cast<const Vec3<float> *>(queries),\n           num_points,\n           num_queries,\n           indices,\n           stream);\n    } else {\n        throw std::runtime_error(\"unsupported scalar type\");\n    }\n}\n\ntemplate <typename coord_scalar>\n__host__ __device__ uint32_t nn_cpu(const Vec3<coord_scalar> *points,\n                                    const AABB<coord_scalar> *aabb_tree,\n                                    const Vec3<coord_scalar> &query,\n                                    uint32_t num_points) {\n    uint32_t base_width = pow2_round_up(num_points);\n    uint32_t tree_depth = log2(base_width);\n\n    coord_scalar min_dist = FLT_MAX;\n    uint32_t index = UINT32_MAX;\n\n    auto functor = [&](uint32_t current_depth, uint32_t current_node) {\n        AABB<coord_scalar> node =\n            get_node(aabb_tree, tree_depth, current_depth, current_node);\n\n        if (current_depth == tree_depth - 1) {\n            uint32_t point_start_idx = current_node * 2;\n\n            for (uint32_t i = 0; i < 2; ++i) {\n                uint32_t point_idx = point_start_idx + i;\n                point_idx = min(point_idx, num_points - 1);\n\n                Vec3f point = points[point_idx];\n\n                float dist = (query - point).norm();\n\n                if (dist < min_dist) {\n                    min_dist = dist;\n                    index = point_idx;\n                }\n            }\n            return TraversalAction::Continue;\n        }\n\n        float dist = node.sdf(query);\n\n        if (dist < min_dist) {\n            return TraversalAction::Continue;\n        } else {\n            return TraversalAction::SkipSubtree;\n        }\n    };\n\n    traverse(num_points, tree_depth - 1, functor);\n\n    return index;\n}\n\nuint32_t nn_cpu(ScalarType coord_scalar_type,\n                const void *coords,\n                const void *aabb_tree,\n                const Vec3f &query,\n                uint32_t num_points) {\n    if (coord_scalar_type == ScalarType::Float32) {\n        return nn_cpu(static_cast<const Vec3<float> *>(coords),\n                      static_cast<const AABB<float> *>(aabb_tree),\n                      query,\n                      num_points);\n    } else {\n        throw std::runtime_error(\"unsupported scalar type\");\n    }\n}\n\n} // namespace radfoam"
  },
  {
    "path": "src/aabb_tree/aabb_tree.cuh",
    "content": "#pragma once\n\n#include <cub/warp/warp_merge_sort.cuh>\n\n#include \"../utils/cuda_array.h\"\n#include \"../utils/geometry.h\"\n#include \"../utils/random.h\"\n#include \"aabb_tree.h\"\n\nnamespace radfoam {\n\n/// @brief Sort the point set into an order appropriate for the leaves of an\n/// AABB tree\nvoid sort_points(CUDAArray<Vec3f> &points_buffer,\n                 uint32_t num_points,\n                 CUDAArray<uint32_t> &permutation);\n\n/// @brief Query a node from the specified level of the AABB tree\ntemplate <typename scalar>\n__forceinline__ __host__ __device__ AABB<scalar>\nget_node(const AABB<scalar> *aabb_tree,\n         uint32_t tree_depth,\n         uint32_t node_depth,\n         uint32_t node_idx) {\n    auto *level_start = aabb_tree + ((1 << tree_depth) - (1 << node_depth + 1));\n    return *(level_start + node_idx);\n}\n\nenum TraversalAction {\n    Continue,\n    SkipSubtree,\n    Terminate,\n};\n\n/// @brief Traverse the AABB tree in a depth-first manner\ntemplate <typename Functor>\n__forceinline__ __host__ __device__ void\ntraverse(uint32_t num_points, uint32_t max_depth, Functor functor) {\n\n    uint32_t current_depth = 0;\n    uint32_t current_node = 0;\n    uint32_t tree_depth = log2(pow2_round_up(num_points));\n\n    for (;;) {\n        auto action = functor(current_depth, current_node);\n\n        if (action == TraversalAction::Terminate) {\n            break;\n        } else if (action == TraversalAction::Continue &&\n                   current_depth != max_depth) {\n            current_node = 2 * current_node;\n            current_depth++;\n            continue;\n        }\n\n        current_node++;\n#ifdef __CUDA_ARCH__\n        uint32_t step_up_amount =\n            min(__ffs(current_node) - 1, (int)current_depth);\n#else\n        uint32_t step_up_amount =\n            min(__builtin_ctz(current_node), (int)current_depth);\n#endif\n        current_depth -= step_up_amount;\n        current_node = current_node >> step_up_amount;\n\n        uint32_t div = tree_depth - current_depth;\n        uint32_t current_width = (num_points + (1 << div) - 1) >> div;\n\n        if (current_node >= current_width)\n            break;\n    }\n}\n\n/// @brief Traverse the AABB tree cooperatively within a warp\ntemplate <int block_size, typename NodeFunctor, typename LeafFunctor>\n__forceinline__ __device__ void warp_traverse(uint32_t num_points,\n                                              NodeFunctor node_functor,\n                                              LeafFunctor leaf_functor) {\n\n    uint32_t base_width = pow2_round_up(num_points);\n    uint32_t tree_depth = log2(base_width);\n\n    uint32_t warp_idx = threadIdx.x / 32;\n    uint8_t idx_in_warp = threadIdx.x % 32;\n    uint32_t current_depth = tree_depth % 5;\n    uint32_t current_node = 0;\n\n    __shared__ uint32_t mask_stack_array[5 * (block_size / 32)];\n    __shared__ uint8_t offset_stack_array[5 * (block_size / 32)];\n    uint32_t *mask_stack = mask_stack_array + 5 * warp_idx;\n    uint8_t *offset_stack = offset_stack_array + 5 * warp_idx;\n    int8_t stack_idx = -1;\n\n    uint8_t current_offset = 0;\n    uint32_t current_mask = 0xffffffff;\n\n    for (;;) {\n        uint32_t div = tree_depth - current_depth;\n        uint32_t current_width = (num_points + (1 << div) - 1) >> div;\n\n        if (current_node >= current_width) {\n            break;\n        }\n\n        bool maskbit = (current_mask >> current_offset) & 1;\n\n        uint32_t thread_node = current_node + idx_in_warp;\n\n        if (maskbit && current_depth == tree_depth) {\n            leaf_functor(thread_node);\n        } else if (maskbit) {\n            TraversalAction action = node_functor(current_depth, thread_node);\n\n            if (__any_sync(0xffffffff, action == TraversalAction::Terminate)) {\n                break;\n            }\n            __syncwarp(0xffffffff);\n            if (idx_in_warp == 0 && stack_idx >= 0) {\n                mask_stack[stack_idx] = current_mask;\n                offset_stack[stack_idx] = current_offset;\n            }\n            __syncwarp(0xffffffff);\n            stack_idx++;\n            current_offset = 0;\n            current_mask =\n                __ballot_sync(0xffffffff, action == TraversalAction::Continue);\n\n            current_node = 32 * current_node;\n            current_depth += 5;\n            continue;\n        }\n\n        current_node += 32;\n        current_offset++;\n\n        while (current_offset == 32) {\n            if (stack_idx < 0) {\n                break;\n            }\n\n            stack_idx--;\n            current_offset = offset_stack[stack_idx];\n            current_mask = mask_stack[stack_idx];\n\n            current_offset++;\n            current_node = current_node >> 5;\n            current_depth -= 5;\n        }\n    }\n}\n\n/// @brief Perform a warp-cooperative k-nearest neighbor search\ntemplate <int block_size, typename scalar>\n__forceinline__ __device__ void warp_knn(const Vec3<scalar> *points,\n                                         const AABB<scalar> *aabb_tree,\n                                         uint32_t num_points,\n                                         const Vec3<scalar> &query,\n                                         uint32_t k,\n                                         scalar *distance_out,\n                                         uint32_t *index_out) {\n    uint32_t base_width = pow2_round_up(num_points);\n    uint32_t tree_depth = log2(base_width);\n\n    uint32_t warp_idx = threadIdx.x / 32;\n    uint8_t idx_in_warp = threadIdx.x % 32;\n\n    using Sort = cub::WarpMergeSort<scalar, 2, 32, uint32_t>;\n    __shared__ typename Sort::TempStorage temp_storage[block_size / 32];\n\n    auto compare = [](auto a, auto b) { return a < b; };\n\n    scalar distance = std::numeric_limits<scalar>::max();\n    uint32_t index = 0;\n    scalar max_distance = std::numeric_limits<scalar>::max();\n\n    scalar local_keys[2];\n    uint32_t local_values[2];\n\n    uint32_t current_depth = 6;\n    uint32_t current_node = 0;\n\n    uint32_t steps = 0;\n\n    auto leaf_functor = [&](uint32_t point_idx) {\n        scalar new_dist = std::numeric_limits<scalar>::max();\n\n        if (point_idx < num_points) {\n            Vec3<scalar> point = points[point_idx];\n            new_dist = (point - query).norm();\n        }\n\n        local_keys[0] = distance;\n        local_keys[1] = new_dist;\n        local_values[0] = index;\n        local_values[1] = point_idx;\n\n        Sort(temp_storage[warp_idx]).Sort(local_keys, local_values, compare);\n\n        scalar d = __shfl_sync(0xffffffff, local_keys[0], idx_in_warp / 2);\n        uint32_t i = __shfl_sync(0xffffffff, local_values[0], idx_in_warp / 2);\n        if (idx_in_warp % 2 == 0) {\n            distance = d;\n            index = i;\n        }\n        d = __shfl_sync(0xffffffff, local_keys[1], idx_in_warp / 2);\n        i = __shfl_sync(0xffffffff, local_values[1], idx_in_warp / 2);\n        if (idx_in_warp % 2 == 1) {\n            distance = d;\n            index = i;\n        }\n\n        scalar new_max_distance = __shfl_sync(0xffffffff, distance, k - 1);\n        if (new_max_distance < max_distance) {\n            max_distance = new_max_distance;\n        }\n\n        steps++;\n    };\n\n    while (current_depth < tree_depth) {\n        AABB<scalar> node0 = get_node(\n            aabb_tree, tree_depth, current_depth, current_node + idx_in_warp);\n        AABB<scalar> node1 = get_node(aabb_tree,\n                                      tree_depth,\n                                      current_depth,\n                                      current_node + idx_in_warp + 32);\n\n        scalar dist0 = node0.sdf(query);\n        scalar dist1 = node1.sdf(query);\n\n        local_keys[0] = dist0;\n        local_keys[1] = dist1;\n        local_values[0] = current_node + idx_in_warp;\n        local_values[1] = current_node + idx_in_warp + 32;\n\n        Sort(temp_storage[warp_idx]).Sort(local_keys, local_values, compare);\n\n        uint32_t best_node = __shfl_sync(0xffffffff, local_values[0], 0);\n\n        uint32_t levels_to_step = min(tree_depth - current_depth, 6);\n\n        current_node = best_node << levels_to_step;\n        current_depth += levels_to_step;\n    }\n\n    current_node = max(current_node - 16, 0u);\n    leaf_functor(current_node + idx_in_warp);\n\n    distance = std::numeric_limits<scalar>::max();\n    index = 0;\n\n    auto node_functor = [&](uint32_t current_depth, uint32_t current_node) {\n        if (current_node >= (1 << current_depth))\n            return TraversalAction::SkipSubtree;\n\n        AABB<scalar> node =\n            get_node(aabb_tree, tree_depth, current_depth, current_node);\n\n        scalar dist = (node.min - query)\n                          .cwiseMax(Vec3<scalar>::Zero())\n                          .cwiseMax(query - node.max)\n                          .norm();\n\n        if (dist > max_distance) {\n            return TraversalAction::SkipSubtree;\n        }\n\n        return TraversalAction::Continue;\n    };\n\n    warp_traverse<block_size>(num_points, node_functor, leaf_functor);\n\n    *distance_out = distance;\n    *index_out = index;\n}\n\n} // namespace radfoam"
  },
  {
    "path": "src/aabb_tree/aabb_tree.h",
    "content": "#pragma once\n\n#include \"../utils/cuda_helpers.h\"\n#include \"../utils/geometry.h\"\n\nnamespace radfoam {\n\n/// @brief Build an AABB tree from a set of points, assuming that the points are\n/// already sorted\nvoid build_aabb_tree(ScalarType scalar_type,\n                     const void *points,\n                     uint32_t num_points,\n                     void *aabb_tree);\n\n/// @brief Find the nearest neighbor of each query point\nvoid nn(ScalarType coord_scalar_type,\n        const void *coords,\n        const void *aabb_tree,\n        const void *query_points,\n        uint32_t num_points,\n        uint32_t num_queries,\n        uint32_t *indices,\n        const void *stream = nullptr);\n\n/// @brief Find the nearest neighbor of a single query point\nuint32_t nn_cpu(ScalarType coord_scalar_type,\n                const void *coords,\n                const void *aabb_tree,\n                const Vec3f &query,\n                uint32_t num_points);\n\n} // namespace radfoam"
  },
  {
    "path": "src/delaunay/delaunay.cu",
    "content": "#include <vector>\n\n#include \"../aabb_tree/aabb_tree.h\"\n\n#include \"delaunay.cuh\"\n\nnamespace radfoam {\n\nvoid check_duplicates(const Vec3f *points, uint32_t num_points) {\n\n    CUDAArray<bool> error_flag_buffer(1);\n    auto error_flag = error_flag_buffer.begin();\n\n    cuda_check(cuMemsetD8((CUdeviceptr)error_flag, 0, 1));\n\n    for_n(u32zero(), num_points - 1, [=] __device__(uint32_t i) {\n        bool duplicate_point = points[i] == points[i + 1];\n        if (duplicate_point) {\n            *error_flag = true;\n        }\n    });\n\n    bool error_flag_host;\n    cuda_check(\n        cuMemcpyDtoH(&error_flag_host, (CUdeviceptr)error_flag, sizeof(bool)));\n\n    if (error_flag_host) {\n        throw TriangulationFailedError(\"duplicate points found\");\n    }\n}\n\nuint32_t find_adjacency(SortedMap<IndexedTet, uint32_t> &tets_map,\n                        SortedMap<IndexedTriangle, uint32_t> &faces_map,\n                        uint32_t num_points,\n                        CUDAArray<uint32_t> &tet_adjacency,\n                        CUDAArray<uint32_t> &point_adjacency,\n                        CUDAArray<uint32_t> &point_adjacency_offset,\n                        CUDAArray<uint32_t> &face_to_tet,\n                        CUDAArray<uint32_t> &vert_to_tet) {\n\n    auto tets = tets_map.unique_keys.begin();\n    auto num_tets = tets_map.num_unique_keys;\n\n    auto faces = faces_map.unique_keys.begin();\n    auto num_faces = faces_map.num_unique_keys;\n\n    vert_to_tet.resize(num_points);\n    auto vert_to_tet_begin = vert_to_tet.begin();\n\n    cuda_check(\n        cuMemsetD32((CUdeviceptr)vert_to_tet_begin, UINT32_MAX, num_points));\n\n    auto write_vert_to_tet = [=] __device__(uint32_t i) {\n        IndexedTet tet = tets[i];\n        for (uint32_t j = 0; j < 4; ++j) {\n            atomicMin(vert_to_tet_begin + tet.vertices[j], i);\n        }\n    };\n\n    for_n(u32zero(), num_tets, write_vert_to_tet);\n\n    CUDAArray<uint32_t> face_adjacent_count(num_faces);\n    auto face_adjacent_count_begin = face_adjacent_count.begin();\n\n    cuda_check(\n        cuMemsetD32((CUdeviceptr)face_adjacent_count_begin, 0, num_faces));\n\n    CUDAArray<uint32_t> tet_face_index(4 * num_tets);\n    auto tet_face_index_begin = tet_face_index.begin();\n\n    face_to_tet.expand(2 * num_faces);\n    auto face_to_tet_begin = face_to_tet.begin_as<uint32_t>();\n\n    cuda_check(\n        cuMemsetD32((CUdeviceptr)face_to_tet_begin, UINT32_MAX, 2 * num_faces));\n\n    CUDAArray<bool> error_flag_buffer(1);\n    auto error_flag = error_flag_buffer.begin();\n\n    cuda_check(cuMemsetD8((CUdeviceptr)error_flag, 0, 1));\n\n    auto write_face_to_tet = [=] __device__(uint32_t i) {\n        IndexedTet tet = tets[i];\n\n        for (uint32_t j = 0; j < 4; ++j) {\n            IndexedTriangle face = tet.face(j);\n\n            auto it = binary_search(faces, faces + num_faces, face);\n\n            if (it == faces + num_faces) {\n                *error_flag = true;\n                return;\n            }\n\n            size_t k = it - faces;\n            uint32_t offset = atomicAdd(face_adjacent_count_begin + k, 1);\n\n            if (offset >= 2) {\n                *error_flag = true;\n                return;\n            }\n\n            face_to_tet_begin[2 * k + offset] = 4 * i + j;\n            tet_face_index_begin[4 * i + j] = k;\n        }\n    };\n\n    for_n(u32zero(), num_tets, write_face_to_tet);\n\n    bool error_flag_host;\n    cuda_check(\n        cuMemcpyDtoH(&error_flag_host, (CUdeviceptr)error_flag, sizeof(bool)));\n\n    if (error_flag_host) {\n        throw TriangulationFailedError(\"ambiguous triangulation\");\n    }\n\n    tet_adjacency.expand(num_tets * 4);\n    auto tet_adjacency_begin = tet_adjacency.begin();\n\n    auto collect_tet_adjacency = [=] __device__(uint32_t i) {\n        uint32_t tet_adjacency[4] = {\n            UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX};\n\n        for (uint32_t j = 0; j < 4; ++j) {\n            uint32_t face_index = tet_face_index_begin[4 * i + j];\n            uint32_t face_adjacent_count =\n                face_adjacent_count_begin[face_index];\n\n            for (uint32_t k = 0; k < face_adjacent_count; ++k) {\n                uint32_t adjacent = face_to_tet_begin[2 * face_index + k];\n                if (adjacent != (4 * i + j)) {\n                    tet_adjacency[j] = adjacent;\n                    break;\n                }\n            }\n        }\n\n        for (uint32_t j = 0; j < 4; ++j) {\n            tet_adjacency_begin[4 * i + j] = tet_adjacency[j];\n        }\n    };\n\n    for_n(u32zero(), num_tets, collect_tet_adjacency);\n\n    CUDAArray<IndexedEdge> edges(6 * num_tets);\n    auto edges_begin = edges.begin();\n\n    auto write_edges = [=] __device__(uint32_t i) {\n        IndexedTet tet = tets[i];\n\n        edges_begin[6 * i + 0] = IndexedEdge(tet.vertices[0], tet.vertices[1]);\n        edges_begin[6 * i + 1] = IndexedEdge(tet.vertices[0], tet.vertices[2]);\n        edges_begin[6 * i + 2] = IndexedEdge(tet.vertices[0], tet.vertices[3]);\n        edges_begin[6 * i + 3] = IndexedEdge(tet.vertices[1], tet.vertices[2]);\n        edges_begin[6 * i + 4] = IndexedEdge(tet.vertices[1], tet.vertices[3]);\n        edges_begin[6 * i + 5] = IndexedEdge(tet.vertices[2], tet.vertices[3]);\n    };\n\n    for_n(u32zero(), num_tets, write_edges);\n\n    CUDAArray<IndexedEdge> edges_temp(6 * num_tets);\n\n    CUB_CALL(cub::DeviceMergeSort::SortKeysCopy(temp_data,\n                                                temp_bytes,\n                                                edges_begin,\n                                                edges_temp.begin(),\n                                                6 * num_tets,\n                                                std::less<IndexedEdge>()));\n\n    CUDAArray<uint32_t> num_unique_edges(1);\n\n    CUB_CALL(cub::DeviceSelect::Unique(temp_data,\n                                       temp_bytes,\n                                       edges_temp.begin(),\n                                       edges_begin,\n                                       num_unique_edges.begin(),\n                                       6 * num_tets));\n\n    uint32_t num_edges;\n\n    cuda_check(cuMemcpyDtoH(\n        &num_edges, (CUdeviceptr)num_unique_edges.begin(), sizeof(uint32_t)));\n\n    CUDAArray<uint32_t> point_adjacency_keys(num_edges * 2);\n    point_adjacency.resize(num_edges * 2);\n    auto point_adjacency_keys_begin = point_adjacency_keys.begin();\n    auto point_adjacency_begin = point_adjacency.begin();\n\n    auto write_point_adjacency_keyval = [=] __device__(uint32_t i) {\n        IndexedEdge edge = edges_begin[i];\n        point_adjacency_keys_begin[2 * i + 0] = edge.vertices[0];\n        point_adjacency_keys_begin[2 * i + 1] = edge.vertices[1];\n        point_adjacency_begin[2 * i + 0] = edge.vertices[1];\n        point_adjacency_begin[2 * i + 1] = edge.vertices[0];\n    };\n\n    for_n(u32zero(), num_edges, write_point_adjacency_keyval);\n\n    CUB_CALL(cub::DeviceMergeSort::SortPairs(temp_data,\n                                             temp_bytes,\n                                             point_adjacency_keys_begin,\n                                             point_adjacency_begin,\n                                             num_edges * 2,\n                                             std::less<uint32_t>()));\n\n    point_adjacency_offset.resize(num_points + 1);\n    auto point_adjacency_offset_begin = point_adjacency_offset.begin();\n\n    cuda_check(cuMemsetD32(\n        (CUdeviceptr)point_adjacency_offset_begin, UINT32_MAX, num_points + 1));\n\n    auto write_point_adjacency_offset = [=] __device__(uint32_t i) {\n        if (i == 0) {\n            point_adjacency_offset_begin[0] = 0;\n            point_adjacency_offset_begin[num_points] = num_edges * 2;\n        } else {\n            uint32_t key0 = point_adjacency_keys_begin[i - 1];\n            uint32_t key1 = point_adjacency_keys_begin[i];\n            if (key0 != key1) {\n                point_adjacency_offset_begin[key0 + 1] = i;\n            }\n        }\n    };\n\n    for_n(u32zero(), num_edges * 2, write_point_adjacency_offset);\n\n    return num_edges * 2;\n}\n\nclass DelaunayTriangulation : public Triangulation {\n  public:\n    virtual ~DelaunayTriangulation() = default;\n\n    explicit DelaunayTriangulation(const Vec3f *points, uint32_t num_points) {\n        rebuild(points, num_points, false);\n    }\n\n    const uint32_t *permutation() const override {\n        return permutation_buffer.begin();\n    }\n\n    uint32_t num_points() const override { return _num_points; }\n\n    const IndexedTet *tets() const override {\n        return tets_map.unique_keys.begin();\n    }\n\n    uint32_t num_tets() const override { return tets_map.num_unique_keys; }\n\n    uint32_t num_faces() const override { return faces_map.num_unique_keys; }\n\n    const uint32_t *tet_adjacency() const override {\n        return tet_adjacency_buffer.begin();\n    }\n\n    const uint32_t *point_adjacency() const override {\n        return point_adjacency_buffer.begin();\n    }\n\n    uint32_t point_adjacency_size() const override {\n        return _point_adjacency_size;\n    }\n\n    const uint32_t *point_adjacency_offsets() const override {\n        return point_adjacency_offset_buffer.begin();\n    }\n\n    const uint32_t *vert_to_tet() const override {\n        return vert_to_tet_buffer.begin();\n    }\n\n    bool rebuild(const void *points_,\n                 uint32_t num_points,\n                 bool incremental) override {\n\n        if (num_points < 32) {\n            throw std::runtime_error(\n                \"Delaunay triangulation does not support less than 32 points\");\n        }\n\n        bool sorted;\n\n        const Vec3f *points = static_cast<const Vec3f *>(points_);\n\n        points_buffer.expand(num_points);\n        copy_range(points, points + num_points, points_buffer.begin());\n\n        uint32_t num_frontier;\n\n        if (incremental && num_points == _num_points) {\n            sorted = false;\n\n            check_duplicates(points_buffer.begin(), num_points);\n\n            aabb_tree_buffer.expand(pow2_round_up(num_points));\n            build_aabb_tree(ScalarType::Float32,\n                            points_buffer.begin(),\n                            num_points,\n                            aabb_tree_buffer.begin());\n\n            num_frontier =\n                delete_delaunay_violations(points_buffer.begin(),\n                                           num_points,\n                                           aabb_tree_buffer.begin(),\n                                           tets_map,\n                                           faces_map,\n                                           frontier_buffer,\n                                           face_to_tet_buffer.begin());\n        } else {\n            _num_points = num_points;\n\n            sort_points(points_buffer, num_points, permutation_buffer);\n\n            check_duplicates(points_buffer.begin(), num_points);\n\n            sorted = true;\n\n            aabb_tree_buffer.expand(pow2_round_up(num_points));\n            build_aabb_tree(ScalarType::Float32,\n                            points_buffer.begin(),\n                            num_points,\n                            aabb_tree_buffer.begin());\n\n            sample_initial_tets(points_buffer.begin(),\n                                num_points,\n                                aabb_tree_buffer.begin(),\n                                tets_map,\n                                faces_map,\n                                num_points);\n\n            num_frontier = faces_map.num_unique_keys;\n            frontier_buffer.expand(num_frontier);\n\n            cuda_check(cuMemcpyDtoD((CUdeviceptr)frontier_buffer.begin(),\n                                    (CUdeviceptr)faces_map.unique_keys.begin(),\n                                    num_frontier * sizeof(IndexedTriangle)));\n        }\n\n        uint32_t num_iterations = 0;\n        while (num_frontier > 0) {\n            num_frontier = growth_iteration(points_buffer.begin(),\n                                            num_points,\n                                            aabb_tree_buffer.begin(),\n                                            tets_map,\n                                            faces_map,\n                                            frontier_buffer,\n                                            num_frontier);\n            num_iterations++;\n\n            if (num_iterations > 500) {\n                throw TriangulationFailedError(\n                    \"growth iteration limit exceeded\");\n            }\n            if (tets_map.num_unique_keys > num_points * 20) {\n                throw TriangulationFailedError(\"divergent growth iterations\");\n            }\n        }\n\n        _point_adjacency_size = find_adjacency(tets_map,\n                                               faces_map,\n                                               _num_points,\n                                               tet_adjacency_buffer,\n                                               point_adjacency_buffer,\n                                               point_adjacency_offset_buffer,\n                                               face_to_tet_buffer,\n                                               vert_to_tet_buffer);\n\n        return sorted;\n    }\n\n  private:\n    uint32_t _num_points;\n    uint32_t _num_convex_hull_points;\n    uint32_t _point_adjacency_size;\n\n    CUDAArray<Vec3f> points_buffer;\n    CUDAArray<uint32_t> permutation_buffer;\n    CUDAArray<AABB<float>> aabb_tree_buffer;\n    SortedMap<IndexedTet, uint32_t> tets_map;\n    SortedMap<IndexedTriangle, uint32_t> faces_map;\n    CUDAArray<IndexedTriangle> frontier_buffer;\n    CUDAArray<uint32_t> tet_adjacency_buffer;\n    CUDAArray<uint32_t> point_adjacency_buffer;\n    CUDAArray<uint32_t> point_adjacency_offset_buffer;\n    CUDAArray<uint32_t> face_to_tet_buffer;\n    CUDAArray<uint32_t> vert_to_tet_buffer;\n};\n\nstd::unique_ptr<Triangulation>\nTriangulation::create_triangulation(const void *points, uint32_t num_points) {\n\n    return std::make_unique<DelaunayTriangulation>(\n        static_cast<const Vec3f *>(points), num_points);\n}\n\n} // namespace radfoam"
  },
  {
    "path": "src/delaunay/delaunay.cuh",
    "content": "#pragma once\n\n#include <vector>\n\n#include <cub/device/device_merge_sort.cuh>\n#include <cub/device/device_partition.cuh>\n#include <cub/device/device_reduce.cuh>\n#include <cub/device/device_scan.cuh>\n#include <cub/device/device_select.cuh>\n#include <cub/iterator/transform_input_iterator.cuh>\n\n#include \"../utils/cuda_helpers.h\"\n#include \"../utils/geometry.h\"\n#include \"delaunay.h\"\n\n#include \"../utils/common_kernels.cuh\"\n#include \"exact_tree_ops.cuh\"\n#include \"sorted_map.cuh\"\n\nnamespace radfoam {\n\n/// @brief Sample num_samples Delaunay tets randomly from the point set\nvoid sample_initial_tets(const Vec3f *points,\n                         uint32_t num_points,\n                         const AABB<float> *aabb_tree,\n                         SortedMap<IndexedTet, uint32_t> &tets_table,\n                         SortedMap<IndexedTriangle, uint32_t> &faces_table,\n                         uint32_t num_samples);\n\n/// @brief Grow the Delaunay mesh by finding tets adjacent to the frontier\nuint32_t growth_iteration(const Vec3f *points,\n                          uint32_t num_points,\n                          const AABB<float> *aabb_tree,\n                          SortedMap<IndexedTet, uint32_t> &tets_table,\n                          SortedMap<IndexedTriangle, uint32_t> &faces_table,\n                          CUDAArray<IndexedTriangle> &frontier,\n                          uint32_t num_frontier);\n\n/// @brief Delete tets that violate the Delaunay condition\nuint32_t\ndelete_delaunay_violations(const Vec3f *points,\n                           uint32_t num_points,\n                           const AABB<float> *aabb_tree,\n                           SortedMap<IndexedTet, uint32_t> &tets_table,\n                           SortedMap<IndexedTriangle, uint32_t> &faces_table,\n                           CUDAArray<IndexedTriangle> &frontier,\n                           const uint32_t *face_to_tet);\n\n} // namespace radfoam"
  },
  {
    "path": "src/delaunay/delaunay.h",
    "content": "#pragma once\n\n#include <memory>\n\n#include \"../utils/geometry.h\"\n\nnamespace radfoam {\n\nclass TriangulationFailedError : public std::runtime_error {\n  public:\n    TriangulationFailedError(const std::string &message)\n        : std::runtime_error(message) {}\n};\n\nclass Triangulation {\n  public:\n    virtual ~Triangulation() = default;\n\n    virtual const uint32_t *permutation() const = 0;\n\n    virtual uint32_t num_points() const = 0;\n\n    virtual const IndexedTet *tets() const = 0;\n\n    virtual uint32_t num_tets() const = 0;\n\n    virtual uint32_t num_faces() const = 0;\n\n    virtual const uint32_t *tet_adjacency() const = 0;\n\n    virtual const uint32_t *point_adjacency() const = 0;\n\n    virtual uint32_t point_adjacency_size() const = 0;\n\n    virtual const uint32_t *point_adjacency_offsets() const = 0;\n\n    virtual const uint32_t *vert_to_tet() const = 0;\n\n    virtual bool\n    rebuild(const void *points, uint32_t num_points, bool incremental) = 0;\n\n    static std::unique_ptr<Triangulation>\n    create_triangulation(const void *points, uint32_t num_points);\n};\n\n} // namespace radfoam"
  },
  {
    "path": "src/delaunay/delete_violations.cu",
    "content": "#include \"delaunay.cuh\"\n\nnamespace radfoam {\n\nconstexpr int DELAUNAY_VIOLATIONS_BLOCK_SIZE = 128;\n\n__global__ void\ndelaunay_violations_kernel(const Vec3f *__restrict__ points,\n                           uint32_t num_points,\n                           const AABB<float> *__restrict__ aabb_tree,\n                           IndexedTet *__restrict__ tets,\n                           uint32_t num_tets,\n                           bool *__restrict__ conditions) {\n    uint32_t i = (blockIdx.x * blockDim.x + threadIdx.x) / 32;\n    uint32_t lane = threadIdx.x % 32;\n\n    if (i >= num_tets) {\n        return;\n    }\n\n    uint32_t steps = 0;\n\n    IndexedTet tet = tets[i];\n    swap(tet.vertices[0], tet.vertices[1]);\n\n    bool condition = check_delaunay_warp<DELAUNAY_VIOLATIONS_BLOCK_SIZE>(\n        points, aabb_tree, num_points, tet, &steps);\n\n    if (lane == 0) {\n        conditions[i] = condition;\n    }\n}\n\nuint32_t\ndelete_delaunay_violations(const Vec3f *points,\n                           uint32_t num_points,\n                           const AABB<float> *aabb_tree,\n                           SortedMap<IndexedTet, uint32_t> &tets_map,\n                           SortedMap<IndexedTriangle, uint32_t> &faces_map,\n                           CUDAArray<IndexedTriangle> &frontier,\n                           const uint32_t *face_to_tet) {\n    auto tets_begin = tets_map.unique_keys.begin();\n    auto num_tets = tets_map.num_unique_keys;\n\n    CUDAArray<bool> conditions(num_tets);\n    auto conditions_begin = conditions.begin();\n\n    launch_kernel_1d<DELAUNAY_VIOLATIONS_BLOCK_SIZE>(delaunay_violations_kernel,\n                                                     num_tets * 32,\n                                                     nullptr,\n                                                     points,\n                                                     num_points,\n                                                     aabb_tree,\n                                                     tets_begin,\n                                                     num_tets,\n                                                     conditions_begin);\n\n    auto faces_begin = faces_map.unique_keys.begin();\n    auto num_faces = faces_map.num_unique_keys;\n\n    CUDAArray<uint8_t> face_status(num_faces);\n    auto face_status_begin = face_status.begin();\n\n    constexpr uint8_t FACE_UNCHANGED = 0;\n    constexpr uint8_t FACE_NOW_FRONTIER = 1;\n    constexpr uint8_t FACE_DELETED = 2;\n\n    auto check_face_status = [=] __device__(uint32_t i) {\n        uint32_t tet_0 = face_to_tet[2 * i + 0] / 4;\n        uint32_t tet_1 = face_to_tet[2 * i + 1] / 4;\n\n        IndexedTriangle face = faces_begin[i];\n        uint32_t adjacent_tet;\n\n        uint8_t status;\n        if (tet_1 == UINT32_MAX / 4) {\n            status = conditions_begin[tet_0] ? FACE_NOW_FRONTIER : FACE_DELETED;\n            adjacent_tet = tet_0;\n        } else {\n            bool cond_0 = conditions_begin[tet_0];\n            bool cond_1 = conditions_begin[tet_1];\n\n            if (cond_0 && cond_1) {\n                status = FACE_UNCHANGED;\n            } else if (cond_0) {\n                status = FACE_NOW_FRONTIER;\n                adjacent_tet = tet_0;\n            } else if (cond_1) {\n                status = FACE_NOW_FRONTIER;\n                adjacent_tet = tet_1;\n            } else {\n                status = FACE_DELETED;\n            }\n        }\n\n        if (status == FACE_NOW_FRONTIER) {\n            IndexedTet adjacent = tets_begin[adjacent_tet];\n\n            for (uint32_t j = 0; j < 4; ++j) {\n                IndexedTriangle adjacent_face = adjacent.face(j);\n                if (face == adjacent_face) {\n                    faces_begin[i] = adjacent_face;\n                }\n            }\n        }\n\n        face_status_begin[i] = status;\n    };\n\n    for_n(u32zero(), num_faces, check_face_status);\n\n    auto enumerated_faces = enumerate<IndexedTriangle>(faces_begin);\n\n    CUDAArray<IndexedTriangle> unchanged_faces_buffer(num_faces);\n    auto unchanged_faces_out =\n        unenumerate<IndexedTriangle>(unchanged_faces_buffer.begin());\n\n    auto select_unchanged_and_frontier =\n        [=] __device__(cub::KeyValuePair<ptrdiff_t, IndexedTriangle> kv) {\n            return face_status_begin[kv.key] == FACE_UNCHANGED ||\n                   face_status_begin[kv.key] == FACE_NOW_FRONTIER;\n        };\n\n    CUDAArray<uint32_t> num_selected_buffer(2);\n    auto num_selected_begin = num_selected_buffer.begin();\n\n    CUB_CALL(cub::DevicePartition::If(temp_data,\n                                      temp_bytes,\n                                      enumerated_faces,\n                                      unchanged_faces_out,\n                                      num_selected_begin,\n                                      num_faces,\n                                      select_unchanged_and_frontier));\n\n    frontier.expand(num_faces);\n    auto frontier_faces_out = unenumerate<IndexedTriangle>(frontier.begin());\n\n    auto select_frontier =\n        [=] __device__(cub::KeyValuePair<ptrdiff_t, IndexedTriangle> kv) {\n            return face_status_begin[kv.key] == FACE_NOW_FRONTIER;\n        };\n\n    CUB_CALL(cub::DevicePartition::If(temp_data,\n                                      temp_bytes,\n                                      enumerated_faces,\n                                      frontier_faces_out,\n                                      num_selected_begin + 1,\n                                      num_faces,\n                                      select_frontier));\n\n    face_status.clear();\n\n    uint32_t num_selected_host[2];\n    cuda_check(cuMemcpyDtoH(&num_selected_host,\n                            (CUdeviceptr)num_selected_begin,\n                            2 * sizeof(uint32_t)));\n\n    uint32_t num_frontier = num_selected_host[1];\n    faces_map.insert(\n        unchanged_faces_buffer.begin(), nullptr, num_selected_host[0]);\n\n    unchanged_faces_buffer.clear();\n\n    CUDAArray<IndexedTet> temp_tets_buffer(num_tets);\n    auto temp_tets_begin = temp_tets_buffer.begin();\n\n    CUB_CALL(cub::DevicePartition::Flagged(temp_data,\n                                           temp_bytes,\n                                           tets_begin,\n                                           conditions_begin,\n                                           temp_tets_begin,\n                                           num_selected_begin,\n                                           num_tets));\n\n    cuda_check(cuMemcpyDtoH(\n        &num_selected_host, (CUdeviceptr)num_selected_begin, sizeof(uint32_t)));\n\n    tets_map.insert(temp_tets_begin, nullptr, num_selected_host[0]);\n\n    return num_frontier;\n}\n\n} // namespace radfoam"
  },
  {
    "path": "src/delaunay/exact_tree_ops.cuh",
    "content": "#pragma once\n\n#include \"../utils/geometry.h\"\n#include \"../utils/random.h\"\n\n#include \"../aabb_tree/aabb_tree.cuh\"\n#include \"predicate.cuh\"\n\nnamespace radfoam {\n\n__forceinline__ __device__ uint32_t warp_broadcast(uint32_t value, bool pred) {\n    uint32_t mask = __ballot_sync(0xffffffff, pred);\n    uint32_t lane_id = __ffs(mask) - 1;\n    return __shfl_sync(0xffffffff, value, lane_id);\n}\n\n/// @brief Find the nearest neighbours of points in the point set\ninline __device__ uint32_t\nvertex_nearest_neighbour(const Vec3f *points,\n                         const AABB<float> *aabb_tree,\n                         uint32_t num_points,\n                         uint32_t q_idx,\n                         uint32_t *steps_out) {\n    uint32_t steps = 0;\n\n    RNGState rng = thread_rng();\n\n    uint32_t base_width = pow2_round_up(num_points);\n    uint32_t tree_depth = log2(base_width);\n\n    Vec3f q = points[q_idx];\n    float dist = FLT_MAX;\n\n    Vec3f tangent;\n    uint32_t tangent_idx;\n\n    uint32_t current_depth = 1;\n    uint32_t current_node = 0;\n    uint32_t points_per_child = base_width >> 2;\n    for (;;) {\n        if (current_depth >= tree_depth) {\n            break;\n        }\n\n        uint32_t pivot = 2 * (current_node + 1) * points_per_child;\n        if (q_idx < pivot) {\n            current_node = 2 * current_node;\n        } else {\n            current_node = 2 * (current_node + 1);\n        }\n\n        uint32_t point_idx = randint(rng,\n                                     current_node * points_per_child,\n                                     (current_node + 1) * points_per_child);\n\n        point_idx = min(point_idx, num_points - 1);\n\n        current_depth++;\n        points_per_child >>= 1;\n\n        if (q_idx == point_idx)\n            continue;\n\n        Vec3f point = points[point_idx];\n\n        float new_dist = (point - q).squaredNorm();\n\n        if (new_dist < dist) {\n            current_depth = 1;\n            current_node = 0;\n            points_per_child = base_width >> 2;\n\n            dist = new_dist;\n            tangent_idx = point_idx;\n            tangent = point;\n        }\n\n        steps++;\n    }\n\n    float radius = __fsqrt_ru(dist);\n\n    auto functor = [&](uint32_t current_depth, uint32_t current_node) {\n        AABB<float> node =\n            get_node(aabb_tree, tree_depth, current_depth, current_node);\n        steps++;\n\n        auto status = node.intersects_sphere(q, radius);\n\n        if (status == IntersectionResult::Outside) {\n            return TraversalAction::SkipSubtree;\n        } else {\n            if (current_depth == tree_depth - 1) {\n                uint32_t point_start_idx = current_node * 2;\n\n                for (uint32_t i = 0; i < 2; ++i) {\n                    uint32_t point_idx = point_start_idx + i;\n                    point_idx = min(point_idx, num_points - 1);\n\n                    if (point_idx == q_idx)\n                        continue;\n\n                    Vec3f point = points[point_idx];\n\n                    float new_dist = (q - point).squaredNorm();\n\n                    if (new_dist < dist) {\n                        dist = new_dist;\n                        radius = __fsqrt_ru(dist);\n                        tangent_idx = point_idx;\n                    }\n                    steps++;\n                }\n            }\n            return TraversalAction::Continue;\n        }\n    };\n\n    traverse(num_points, tree_depth - 1, functor);\n\n    if (steps_out)\n        *steps_out += steps;\n\n    return tangent_idx;\n}\n\n/// @brief Check if tetrahedra satisfy the Delaunay condition\ntemplate <int block_size>\n__forceinline__ __device__ bool check_delaunay(const Vec3f *points,\n                                               const AABB<float> *aabb_tree,\n                                               uint32_t num_points,\n                                               const IndexedTet &tet,\n                                               uint32_t *steps_out) {\n    uint32_t steps = 0;\n\n    Vec3f v0 = points[tet.vertices[0]];\n    Vec3f v1 = points[tet.vertices[1]];\n    Vec3f v2 = points[tet.vertices[2]];\n    Vec3f v3 = points[tet.vertices[3]];\n\n    EmptyCircumspherePredicate predicate(v0, v1, v2);\n    predicate.update(v3);\n\n    if (HalfspacePredicate(v0, v2, v1).check_point(v3)) {\n        return false;\n    }\n\n    uint32_t base_width = pow2_round_up(num_points);\n    uint32_t tree_depth = log2(base_width);\n\n    bool condition = true;\n\n    auto functor = [&](uint32_t current_depth, uint32_t current_node) {\n        AABB<float> node =\n            get_node(aabb_tree, tree_depth, current_depth, current_node);\n        steps++;\n\n        if (!predicate.check_aabb_conservative(node)) {\n            return TraversalAction::SkipSubtree;\n        }\n\n        if (current_depth == tree_depth - 1) {\n            uint32_t point_start_idx = current_node * 2;\n\n            for (uint32_t i = 0; i < 2; ++i) {\n                uint32_t point_idx = point_start_idx + i;\n                point_idx = min(point_idx, num_points - 1);\n\n                bool should_ignore = false;\n                for (uint32_t j = 0; j < 4; ++j) {\n                    if (point_idx == tet.vertices[j]) {\n                        should_ignore = true;\n                        break;\n                    }\n                }\n\n                if (should_ignore)\n                    continue;\n\n                Vec3f point = points[point_idx];\n\n                steps++;\n\n                if (predicate.check_point(point)) {\n                    condition = false;\n                    return TraversalAction::Terminate;\n                }\n            }\n        }\n        return TraversalAction::Continue;\n    };\n\n    traverse(num_points, tree_depth - 1, functor);\n\n    if (steps_out)\n        *steps_out += steps;\n\n    return condition;\n}\n\n/// @brief Check if tetrahedra satisfy the Delaunay condition (warp cooperative)\ntemplate <int block_size>\n__forceinline__ __device__ bool\ncheck_delaunay_warp(const Vec3f *points,\n                    const AABB<float> *aabb_tree,\n                    uint32_t num_points,\n                    const IndexedTet &tet,\n                    uint32_t *steps_out) {\n    uint32_t steps = 0;\n\n    uint32_t base_width = pow2_round_up(num_points);\n    uint32_t tree_depth = log2(base_width);\n\n    Vec3f v0 = points[tet.vertices[0]];\n    Vec3f v1 = points[tet.vertices[1]];\n    Vec3f v2 = points[tet.vertices[2]];\n    Vec3f v3 = points[tet.vertices[3]];\n\n    EmptyCircumspherePredicate predicate(v0, v1, v2);\n    predicate.update(v3);\n\n    if (HalfspacePredicate(v0, v2, v1).check_point(v3)) {\n        return false;\n    }\n\n    __syncwarp(0xffffffff);\n\n    bool condition = true;\n\n    auto leaf_functor = [&](uint32_t point_idx) {\n        point_idx = min(point_idx, num_points - 1);\n\n        bool should_ignore = false;\n        for (uint32_t j = 0; j < 4; ++j) {\n            if (point_idx == tet.vertices[j]) {\n                should_ignore = true;\n                break;\n            }\n        }\n\n        Vec3f point = points[point_idx];\n\n        steps++;\n\n        bool flag = predicate.check_point(point, true) && !should_ignore;\n\n        if (!__any_sync(0xffffffff, flag)) {\n            return;\n        }\n\n        flag = predicate.check_point(point) && !should_ignore;\n\n        if (__any_sync(0xffffffff, flag)) {\n            condition = false;\n        }\n    };\n\n    auto node_functor = [&](uint32_t current_depth, uint32_t current_node) {\n        if (!condition)\n            return TraversalAction::Terminate;\n\n        if (current_node >= (1 << current_depth))\n            return TraversalAction::SkipSubtree;\n\n        AABB<float> node =\n            get_node(aabb_tree, tree_depth, current_depth, current_node);\n        steps++;\n\n        if (!predicate.check_aabb_conservative(node)) {\n            return TraversalAction::SkipSubtree;\n        }\n\n        return TraversalAction::Continue;\n    };\n\n    warp_traverse<block_size>(num_points, node_functor, leaf_functor);\n\n    if (steps_out)\n        *steps_out += steps;\n\n    return condition;\n}\n\n/// @brief Find the largest empty sphere that intersects three vertices from the\n/// exterior of the triangulation (warp cooperative)\ntemplate <int block_size>\ninline __device__ uint32_t maximal_empty_sphere(const Vec3f *points,\n                                                const AABB<float> *aabb_tree,\n                                                uint32_t num_points,\n                                                const Vec3f &v0,\n                                                const Vec3f &v1,\n                                                const Vec3f &v2,\n                                                uint32_t t0,\n                                                uint32_t t1,\n                                                uint32_t t2,\n                                                uint32_t num_tangent,\n                                                uint32_t *steps_out,\n                                                bool *found_out) {\n    uint32_t steps = 0;\n\n    RNGState rng = thread_rng();\n\n    uint32_t base_width = pow2_round_up(num_points);\n    uint32_t tree_depth = log2(base_width);\n\n    EmptyCircumspherePredicate sphere_predicate(v0, v1, v2);\n    HalfspacePredicate plane_predicate(v0, v1, v2);\n\n    __syncwarp(0xffffffff);\n\n    uint32_t tangent_idx = 0;\n    bool found = false;\n\n    auto tangent_inds = [&](uint32_t k) {\n        switch (k) {\n        case 0:\n            return t0;\n        case 1:\n            return t1;\n        case 2:\n            return t2;\n        }\n        return UINT32_MAX;\n    };\n\n    uint32_t k = 0;\n    for (uint32_t i = 0; i < 16; ++i) {\n        k = (k + 1) % num_tangent;\n        Vec3i t = inverse_morton_code(tangent_inds(k));\n        Vec3f offset = randn3(rng) * 4.0f;\n        t += offset.template cast<int32_t>();\n        t = t.cwiseMax(Vec3i::Zero());\n        uint32_t point_idx = morton_code(t);\n        point_idx = min(point_idx, num_points - 1);\n\n        bool should_ignore = false;\n        for (uint32_t j = 0; j < num_tangent; ++j) {\n            if (point_idx == tangent_inds(j)) {\n                should_ignore = true;\n                break;\n            }\n        }\n\n        Vec3f point = points[point_idx];\n\n        steps++;\n\n        bool flag = (plane_predicate.check_point(point, true) &&\n                     sphere_predicate.check_point(point, true));\n        flag &= !should_ignore;\n\n        if (!__any_sync(0xffffffff, flag)) {\n            continue;\n        }\n\n        flag = (plane_predicate.check_point(point) &&\n                sphere_predicate.check_point(point));\n        flag &= !should_ignore;\n\n        if (__any_sync(0xffffffff, flag)) {\n            bool pred = sphere_predicate.warp_update(point, flag, found);\n            tangent_idx = warp_broadcast(point_idx, pred);\n        }\n    }\n\n    auto leaf_functor = [&](uint32_t point_idx) {\n        point_idx = min(point_idx, num_points - 1);\n\n        bool should_ignore = false;\n        for (uint32_t j = 0; j < num_tangent; ++j) {\n            if (point_idx == tangent_inds(j)) {\n                should_ignore = true;\n                break;\n            }\n        }\n\n        Vec3f point = points[point_idx];\n\n        steps++;\n\n        bool flag = (plane_predicate.check_point(point, true) &&\n                     sphere_predicate.check_point(point, true));\n        flag &= !should_ignore;\n\n        if (!__any_sync(0xffffffff, flag)) {\n            return;\n        }\n\n        flag = (plane_predicate.check_point(point) &&\n                sphere_predicate.check_point(point));\n        flag &= !should_ignore;\n\n        if (__any_sync(0xffffffff, flag)) {\n            bool pred = sphere_predicate.warp_update(point, flag, found);\n            tangent_idx = warp_broadcast(point_idx, pred);\n        }\n    };\n\n    auto node_functor = [&](uint32_t current_depth, uint32_t current_node) {\n        if (current_node >= (1 << current_depth))\n            return TraversalAction::SkipSubtree;\n\n        AABB<float> node =\n            get_node(aabb_tree, tree_depth, current_depth, current_node);\n        steps++;\n\n        if (!plane_predicate.check_aabb_conservative(node)) {\n            return TraversalAction::SkipSubtree;\n        }\n\n        if (!sphere_predicate.check_aabb_conservative(node)) {\n            return TraversalAction::SkipSubtree;\n        }\n\n        return TraversalAction::Continue;\n    };\n\n    warp_traverse<block_size>(num_points, node_functor, leaf_functor);\n\n    if (steps_out)\n        *steps_out += steps;\n\n    if (found_out)\n        *found_out = found;\n\n    return tangent_idx;\n}\n\n} // namespace radfoam"
  },
  {
    "path": "src/delaunay/growth_iteration.cu",
    "content": "#include \"delaunay.cuh\"\n\nnamespace radfoam {\n\nconstexpr int GROWTH_ITERATION_BLOCK_SIZE = 128;\n\n__global__ void\ngrowth_iteration_kernel(const Vec3f *__restrict__ points,\n                        uint32_t num_points,\n                        const AABB<float> *__restrict__ aabb_tree,\n                        const IndexedTriangle *__restrict__ frontier,\n                        uint32_t num_frontier,\n                        IndexedTet *__restrict__ new_tets,\n                        IndexedTriangle *__restrict__ new_faces) {\n    uint32_t i = (blockIdx.x * blockDim.x + threadIdx.x) / 32;\n    uint32_t lane = threadIdx.x % 32;\n\n    if (i >= num_frontier) {\n        return;\n    }\n\n    IndexedTriangle seed_face = frontier[i];\n    Vec3f v0 = points[seed_face.vertices[0]];\n    Vec3f v1 = points[seed_face.vertices[1]];\n    Vec3f v2 = points[seed_face.vertices[2]];\n\n    IndexedTet tet;\n    tet.vertices[0] = seed_face.vertices[0];\n    tet.vertices[1] = seed_face.vertices[1];\n    tet.vertices[2] = seed_face.vertices[2];\n\n    uint32_t steps = 0;\n    bool found;\n    tet.vertices[3] =\n        maximal_empty_sphere<GROWTH_ITERATION_BLOCK_SIZE>(points,\n                                                          aabb_tree,\n                                                          num_points,\n                                                          v0,\n                                                          v1,\n                                                          v2,\n                                                          tet.vertices[0],\n                                                          tet.vertices[1],\n                                                          tet.vertices[2],\n                                                          3,\n                                                          &steps,\n                                                          &found);\n\n    if (lane != 0) {\n        return;\n    }\n\n    Vec3f v3 = points[tet.vertices[3]];\n\n    IndexedTriangle faces[3];\n    uint32_t j = 0;\n    if (found) {\n        Vec3f n = (v1 - v0).cross((v2 - v1));\n        if (n.dot((v0 - v3)) < 0) {\n            swap(tet.vertices[0], tet.vertices[1]);\n        }\n\n        for (uint32_t k = 0; k < 4; ++k) {\n            auto face = tet.face(k);\n            if (face != seed_face) {\n                switch (j) { // Avoid spilling to local memory\n                case 0:\n                    faces[0] = face;\n                    break;\n                case 1:\n                    faces[1] = face;\n                    break;\n                case 2:\n                    faces[2] = face;\n                    break;\n                }\n                j++;\n            }\n        }\n    } else {\n        uint32_t max = UINT32_MAX;\n\n        tet.vertices[0] = max;\n        tet.vertices[1] = max;\n        tet.vertices[2] = max;\n        tet.vertices[3] = max;\n\n        faces[0] = IndexedTriangle(max, max, max);\n        faces[1] = IndexedTriangle(max, max, max);\n        faces[2] = IndexedTriangle(max, max, max);\n    }\n\n    new_tets[i] = tet;\n    new_faces[i * 3 + 0] = faces[0];\n    new_faces[i * 3 + 1] = faces[1];\n    new_faces[i * 3 + 2] = faces[2];\n}\n\nuint32_t growth_iteration(const Vec3f *points,\n                          uint32_t num_points,\n                          const AABB<float> *aabb_tree,\n                          SortedMap<IndexedTet, uint32_t> &tets_map,\n                          SortedMap<IndexedTriangle, uint32_t> &faces_map,\n                          CUDAArray<IndexedTriangle> &frontier,\n                          uint32_t num_frontier) {\n\n    frontier.expand(num_frontier * 3, true);\n    auto frontier_begin = frontier.begin();\n\n    CUDAArray<IndexedTet> new_tets(num_frontier * 2);\n    auto new_tets_begin = new_tets.begin();\n\n    CUDAArray<IndexedTriangle> new_faces(num_frontier * 6);\n    auto new_faces_begin = new_faces.begin();\n\n    launch_kernel_1d<GROWTH_ITERATION_BLOCK_SIZE>(growth_iteration_kernel,\n                                                  num_frontier * 32,\n                                                  nullptr,\n                                                  points,\n                                                  num_points,\n                                                  aabb_tree,\n                                                  frontier_begin,\n                                                  num_frontier,\n                                                  new_tets_begin,\n                                                  new_faces_begin);\n    SortedMap<IndexedTet, uint32_t> new_tets_map;\n    new_tets_map.num_unique_keys = num_frontier;\n    new_tets_map.insert(new_tets_begin, nullptr, num_frontier);\n    auto unique_new_tets_begin = new_tets_map.unique_keys.begin();\n    uint32_t num_new_tets = new_tets_map.num_unique_keys;\n\n    new_tets.clear();\n\n    SortedMap<IndexedTriangle, uint32_t> new_faces_map;\n    new_faces_map.num_unique_keys = num_frontier * 3;\n    new_faces_map.insert(new_faces_begin, nullptr, num_frontier * 3);\n    auto unique_new_faces_begin = new_faces_map.unique_keys.begin();\n    uint32_t num_new_faces = new_faces_map.num_unique_keys;\n\n    new_faces.clear();\n\n    CUDAArray<uint32_t> num_selected(2);\n    auto num_selected_begin = num_selected.begin();\n\n    uint32_t num_tets = tets_map.num_unique_keys;\n\n    CUDAArray<IndexedTet> tets(num_tets + num_frontier);\n    auto tets_begin = tets.begin();\n    IndexedTet *tets_end = tets_begin + num_tets;\n\n    copy_range(tets_map.unique_keys.begin(),\n               tets_map.unique_keys.begin() + num_tets,\n               tets_begin);\n\n    CUDAArray<bool> flags(3 * num_frontier);\n    auto flags_begin = flags.begin();\n\n    auto check_tets = [=] __device__(uint32_t i) {\n        IndexedTet tet = unique_new_tets_begin[i];\n        if (tet.vertices[0] == UINT32_MAX) {\n            flags_begin[i] = false;\n            return;\n        }\n\n        auto it = binary_search(tets_begin, tets_end, tet);\n\n        flags_begin[i] = it == tets_end;\n    };\n\n    for_n(u32zero(), num_new_tets, check_tets);\n\n    CUB_CALL(cub::DeviceSelect::Flagged(temp_data,\n                                        temp_bytes,\n                                        unique_new_tets_begin,\n                                        flags_begin,\n                                        tets_end,\n                                        num_selected_begin,\n                                        num_new_tets));\n\n    cuda_check(cuMemcpyDtoH(\n        &num_new_tets, (CUdeviceptr)num_selected_begin, sizeof(uint32_t)));\n    num_tets += num_new_tets;\n    tets_map.insert(tets_begin, nullptr, num_tets);\n\n    tets.clear();\n\n    uint32_t num_faces = faces_map.num_unique_keys;\n\n    CUDAArray<IndexedTriangle> faces(num_faces + 3 * num_frontier);\n    auto faces_begin = faces.begin();\n    copy_range(faces_map.unique_keys.begin(),\n               faces_map.unique_keys.begin() + num_faces,\n               faces_begin);\n    IndexedTriangle *faces_end = faces_begin + num_faces;\n\n    auto check_faces = [=] __device__(uint32_t i) {\n        IndexedTriangle face = unique_new_faces_begin[i];\n        if (face.vertices[0] == UINT32_MAX) {\n            flags_begin[i] = false;\n            return;\n        }\n\n        auto it = binary_search(faces_begin, faces_end, face);\n\n        flags_begin[i] = it == faces_end;\n    };\n    for_n(u32zero(), num_new_faces, check_faces);\n\n    CUB_CALL(cub::DeviceSelect::Flagged(temp_data,\n                                        temp_bytes,\n                                        unique_new_faces_begin,\n                                        flags_begin,\n                                        frontier_begin,\n                                        num_selected_begin + 1,\n                                        num_new_faces));\n\n    cuda_check(cuMemcpyDtoH(&num_new_faces,\n                            (CUdeviceptr)(num_selected_begin + 1),\n                            sizeof(uint32_t)));\n\n    num_frontier = num_new_faces;\n    num_faces += num_frontier;\n\n    copy_range(frontier_begin, frontier_begin + num_frontier, faces_end);\n\n    faces_map.insert(faces_begin, nullptr, num_faces);\n\n    return num_frontier;\n}\n\n} // namespace radfoam"
  },
  {
    "path": "src/delaunay/predicate.cuh",
    "content": "#pragma once\n\n#include \"../utils/geometry.h\"\n#include \"shewchuk.cuh\"\n\nnamespace radfoam {\n\nstruct HalfspacePredicate {\n    const Vec3f *v0;\n    const Vec3f *v1;\n    const Vec3f *v2;\n\n    __forceinline__ __device__ HalfspacePredicate(const Vec3f &v0,\n                                                  const Vec3f &v1,\n                                                  const Vec3f &v2)\n        : v0(&v0), v1(&v1), v2(&v2) {}\n\n    __forceinline__ __device__ bool\n    check_point(const Vec3f &v3, bool conservative = false) const {\n        if (conservative) {\n            return orient3dconservative(*v0, *v1, v3, *v2) ==\n                   PredicateResult::Inside;\n        } else {\n            return orient3d(*v0, *v1, v3, *v2) == PredicateResult::Inside;\n        }\n    }\n\n    __forceinline__ __device__ bool\n    check_aabb_conservative(const AABB<float> &aabb) const {\n        bool inside = false;\n#pragma unroll\n        for (int i = 0; i < 8; ++i) {\n            Vec3f corner((i & 1) ? aabb.min[0] : aabb.max[0],\n                         (i & 2) ? aabb.min[1] : aabb.max[1],\n                         (i & 4) ? aabb.min[2] : aabb.max[2]);\n            inside |= check_point(corner, true);\n        }\n        return inside;\n    }\n};\n\nstruct EmptyCircumspherePredicate {\n    const Vec3f *v0;\n    const Vec3f *v1;\n    const Vec3f *v2;\n    Vec3f v3;\n    Vec3f c;\n\n    __forceinline__ __device__ EmptyCircumspherePredicate(const Vec3f &v0,\n                                                          const Vec3f &v1,\n                                                          const Vec3f &v2)\n        : v0(&v0), v1(&v1), v2(&v2), c(Vec3f::Zero()) {\n        c = Vec3f(std::numeric_limits<float>::infinity(),\n                  std::numeric_limits<float>::infinity(),\n                  std::numeric_limits<float>::infinity());\n        v3 = Vec3f(std::numeric_limits<float>::infinity(),\n                   std::numeric_limits<float>::infinity(),\n                   std::numeric_limits<float>::infinity());\n    }\n\n    inline __device__ bool check_point(const Vec3f &v3_new,\n                                       bool conservative = false) const {\n        if (!isfinite(v3[0])) {\n            return true;\n        }\n        if (conservative) {\n            return insphereconservative(*v0, *v1, *v2, v3_new, v3) ==\n                   PredicateResult::Inside;\n        } else {\n            return insphere(*v0, *v1, *v2, v3_new, v3) ==\n                   PredicateResult::Inside;\n        }\n    }\n\n    inline __device__ bool\n    check_aabb_conservative(const AABB<float> &aabb) const {\n        if (!isfinite(c[0])) {\n            return true;\n        }\n        Vec3f x = c.cwiseMin(aabb.max).cwiseMax(aabb.min);\n        return check_point(x, true);\n    }\n\n    __forceinline__ __device__ bool\n    warp_update(const Vec3f &v3_new, bool valid, bool &found) {\n        uint32_t valid_mask = __ballot_sync(0xffffffff, valid);\n        uint32_t lane_id = threadIdx.x % 32;\n        bool is_best_lane = false;\n        for (uint32_t i = 0; i < 32; ++i) {\n            if (valid_mask & (1 << i)) {\n                Vec3f v3i;\n                v3i[0] = __shfl_sync(0xffffffff, v3_new[0], i);\n                v3i[1] = __shfl_sync(0xffffffff, v3_new[1], i);\n                v3i[2] = __shfl_sync(0xffffffff, v3_new[2], i);\n\n                if (!found || check_point(v3i)) {\n                    found = true;\n                    update(v3i);\n                    is_best_lane = lane_id == i;\n                }\n            }\n        }\n        return is_best_lane;\n    }\n\n    __forceinline__ __device__ void update(const Vec3f &v3_new) {\n        v3 = v3_new;\n\n        Vec3f u0 = *v1 - *v0;\n        Vec3f u1 = *v2 - *v0;\n        Vec3f u2 = v3 - *v0;\n\n        Vec3f w0 = u0.cross(u1);\n        Vec3f w1 = u1.cross(u2);\n        Vec3f w2 = u2.cross(u0);\n\n        float vol = u0.dot(w1) / 6;\n        Vec3f num = u0.squaredNorm() * w1 + u1.squaredNorm() * w2 +\n                    u2.squaredNorm() * w0;\n        Vec3f x = num / (12 * vol);\n\n        if (isfinite(x[0]) && isfinite(x[1]) && isfinite(x[2])) {\n            c = x + *v0;\n        }\n    }\n};\n\n} // namespace radfoam"
  },
  {
    "path": "src/delaunay/sample_initial_tets.cu",
    "content": "#include \"delaunay.cuh\"\n\nnamespace radfoam {\n\nconstexpr int SAMPLE_INITIAL_TETS_BLOCK_SIZE = 128;\n\n__global__ void sample_initial_tets_kernel(const Vec3f *points,\n                                           uint32_t num_points,\n                                           const AABB<float> *aabb_tree,\n                                           IndexedTet *tets,\n                                           IndexedTriangle *faces,\n                                           uint32_t num_samples) {\n\n    uint32_t i = (blockIdx.x * blockDim.x + threadIdx.x) / 32;\n    uint32_t lane = threadIdx.x % 32;\n\n    if (i >= num_samples) {\n        return;\n    }\n\n    uint32_t steps = 0;\n\n    IndexedTet tet;\n    RNGState rng = make_rng(i);\n\n    Vec3f v0, v1, v2, v3;\n\n    bool found = false;\n    for (;;) {\n        tet.vertices[0] = i % num_points;\n\n        uint32_t nn_idx;\n\n        if (lane == 0) {\n            nn_idx = vertex_nearest_neighbour(\n                points, aabb_tree, num_points, tet.vertices[0], &steps);\n        }\n\n        tet.vertices[1] = __shfl_sync(0xffffffff, nn_idx, 0);\n\n        v0 = points[tet.vertices[0]];\n        v1 = points[tet.vertices[1]];\n\n        Vec3f c = (v0 + v1) / 2;\n        Vec3f d0 = v1 - v0;\n        float r_squared = d0.squaredNorm() / 4;\n        Vec3f dr = randn3(rng);\n        Vec3f n = d0.cross(dr.normalized());\n        Vec3f d1 = n.cross(d0);\n        d1.normalize();\n        v2 = c + d1 * sqrt(r_squared);\n\n        tet.vertices[2] = maximal_empty_sphere<SAMPLE_INITIAL_TETS_BLOCK_SIZE>(\n            points,\n            aabb_tree,\n            num_points,\n            v0,\n            v1,\n            v2,\n            tet.vertices[0],\n            tet.vertices[1],\n            UINT32_MAX,\n            2,\n            &steps,\n            &found);\n        if (!found) {\n            break;\n        }\n\n        v2 = points[tet.vertices[2]];\n\n        tet.vertices[3] = maximal_empty_sphere<SAMPLE_INITIAL_TETS_BLOCK_SIZE>(\n            points,\n            aabb_tree,\n            num_points,\n            v0,\n            v1,\n            v2,\n            tet.vertices[0],\n            tet.vertices[1],\n            tet.vertices[2],\n            3,\n            &steps,\n            &found);\n\n        if (!found) {\n            break;\n        }\n\n        v3 = points[tet.vertices[3]];\n\n        if (!found) {\n            break;\n        }\n\n        found = check_delaunay<SAMPLE_INITIAL_TETS_BLOCK_SIZE>(\n            points, aabb_tree, num_points, tet, nullptr);\n\n        break;\n    }\n\n    if (lane != 0) {\n        return;\n    }\n\n    IndexedTriangle _faces[4];\n\n    if (found) {\n        Vec3f n = tet.face(0).normal(v0, v1, v2);\n        if (n.dot(v0 - v3) < 0) {\n            swap(tet.vertices[0], tet.vertices[1]);\n        }\n\n        _faces[0] = tet.face(0);\n        _faces[1] = tet.face(1);\n        _faces[2] = tet.face(2);\n        _faces[3] = tet.face(3);\n    } else {\n        uint32_t max = UINT32_MAX;\n\n        tet.vertices[0] = max;\n        tet.vertices[1] = max;\n        tet.vertices[2] = max;\n        tet.vertices[3] = max;\n\n        _faces[0] = IndexedTriangle(max, max, max);\n        _faces[1] = IndexedTriangle(max, max, max);\n        _faces[2] = IndexedTriangle(max, max, max);\n        _faces[3] = IndexedTriangle(max, max, max);\n    }\n    tets[i] = tet;\n    faces[i * 4 + 0] = _faces[0];\n    faces[i * 4 + 1] = _faces[1];\n    faces[i * 4 + 2] = _faces[2];\n    faces[i * 4 + 3] = _faces[3];\n}\n\nvoid sample_initial_tets(const Vec3f *points,\n                         uint32_t num_points,\n                         const AABB<float> *aabb_tree,\n                         SortedMap<IndexedTet, uint32_t> &tets_map,\n                         SortedMap<IndexedTriangle, uint32_t> &faces_map,\n                         uint32_t num_samples) {\n\n    CUDAArray<IndexedTet> temp_tets(num_samples);\n    IndexedTet *temp_tets_begin = temp_tets.begin();\n\n    CUDAArray<IndexedTriangle> temp_faces(num_samples * 4);\n    IndexedTriangle *temp_faces_begin = temp_faces.begin();\n\n    launch_kernel_1d<SAMPLE_INITIAL_TETS_BLOCK_SIZE>(sample_initial_tets_kernel,\n                                                     num_samples * 32,\n                                                     nullptr,\n                                                     points,\n                                                     num_points,\n                                                     aabb_tree,\n                                                     temp_tets_begin,\n                                                     temp_faces_begin,\n                                                     num_samples);\n\n    tets_map.insert(temp_tets_begin, nullptr, num_samples);\n    faces_map.insert(temp_faces_begin, nullptr, num_samples * 4);\n}\n\n} // namespace radfoam"
  },
  {
    "path": "src/delaunay/shewchuk.cuh",
    "content": "#pragma once\n\n#include <stdexcept>\n\n#include \"../utils/geometry.h\"\n\nnamespace radfoam {\n\n/*****************************************************************************/\n/*                                                                           */\n/*  Routines for Arbitrary Precision Floating-point Arithmetic               */\n/*  and Fast Robust Geometric Predicates                                     */\n/*  (predicates.c)                                                           */\n/*                                                                           */\n/*  May 18, 1996                                                             */\n/*                                                                           */\n/*  Placed in the public domain by                                           */\n/*  Jonathan Richard Shewchuk                                                */\n/*  School of Computer Science                                               */\n/*  Carnegie Mellon University                                               */\n/*  5000 Forbes Avenue                                                       */\n/*  Pittsburgh, Pennsylvania  15213-3891                                     */\n/*  jrs@cs.cmu.edu                                                           */\n/*                                                                           */\n/*  This file contains C implementation of algorithms for exact addition     */\n/*    and multiplication of floating-point numbers, and predicates for       */\n/*    robustly performing the orientation and incircle tests used in         */\n/*    computational geometry.  The algorithms and underlying theory are      */\n/*    described in Jonathan Richard Shewchuk.  \"Adaptive Precision Floating- */\n/*    Point Arithmetic and Fast Robust Geometric Predicates.\"  Technical     */\n/*    Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon      */\n/*    University, Pittsburgh, Pennsylvania, May 1996.  (Submitted to         */\n/*    Discrete & Computational Geometry.)                                    */\n/*                                                                           */\n/*  This file, the paper listed above, and other information are available   */\n/*    from the Web page http://www.cs.cmu.edu/~quake/robust.html .           */\n/*                                                                           */\n/*****************************************************************************/\n\n/*****************************************************************************/\n/*                                                                           */\n/*  Using this code:                                                         */\n/*                                                                           */\n/*  First, read the short or long version of the paper (from the Web page    */\n/*    above).                                                                */\n/*                                                                           */\n/*  Be sure to call exactinit() once, before calling any of the arithmetic   */\n/*    functions or geometric predicates.  Also be sure to turn on the        */\n/*    optimizer when compiling this file.                                    */\n/*                                                                           */\n/*                                                                           */\n/*  Several geometric predicates are defined.  Their parameters are all      */\n/*    points.  Each point is an array of two or three floating-point         */\n/*    numbers.  The geometric predicates, described in the papers, are       */\n/*                                                                           */\n/*    orient2d(pa, pb, pc)                                                   */\n/*    orient2dfast(pa, pb, pc)                                               */\n/*    orient3d(pa, pb, pc, pd)                                               */\n/*    orient3dfast(pa, pb, pc, pd)                                           */\n/*    incircle(pa, pb, pc, pd)                                               */\n/*    incirclefast(pa, pb, pc, pd)                                           */\n/*    insphere(pa, pb, pc, pd, pe)                                           */\n/*    inspherefast(pa, pb, pc, pd, pe)                                       */\n/*                                                                           */\n/*  Those with suffix \"fast\" are approximate, non-robust versions.  Those    */\n/*    without the suffix are adaptive precision, robust versions.  There     */\n/*    are also versions with the suffices \"exact\" and \"slow\", which are      */\n/*    non-adaptive, exact arithmetic versions, which I use only for timings  */\n/*    in my arithmetic papers.                                               */\n/*                                                                           */\n/*                                                                           */\n/*  An expansion is represented by an array of floating-point numbers,       */\n/*    sorted from smallest to largest magnitude (possibly with interspersed  */\n/*    zeros).  The length of each expansion is stored as a separate integer, */\n/*    and each arithmetic function returns an integer which is the length    */\n/*    of the expansion it created.                                           */\n/*                                                                           */\n/*  Several arithmetic functions are defined.  Their parameters are          */\n/*                                                                           */\n/*    e, f           Input expansions                                        */\n/*    elen, flen     Lengths of input expansions (must be >= 1)              */\n/*    h              Output expansion                                        */\n/*    b              Input scalar                                            */\n/*                                                                           */\n/*  The arithmetic functions are                                             */\n/*                                                                           */\n/*    grow_expansion(elen, e, b, h)                                          */\n/*    grow_expansion_zeroelim(elen, e, b, h)                                 */\n/*    expansion_sum(elen, e, flen, f, h)                                     */\n/*    expansion_sum_zeroelim1(elen, e, flen, f, h)                           */\n/*    expansion_sum_zeroelim2(elen, e, flen, f, h)                           */\n/*    fast_expansion_sum(elen, e, flen, f, h)                                */\n/*    fast_expansion_sum_zeroelim(elen, e, flen, f, h)                       */\n/*    linear_expansion_sum(elen, e, flen, f, h)                              */\n/*    linear_expansion_sum_zeroelim(elen, e, flen, f, h)                     */\n/*    scale_expansion(elen, e, b, h)                                         */\n/*    scale_expansion_zeroelim(elen, e, b, h)                                */\n/*    compress(elen, e, h)                                                   */\n/*                                                                           */\n/*  All of these are described in the long version of the paper; some are    */\n/*    described in the short version.  All return an integer that is the     */\n/*    length of h.  Those with suffix _zeroelim perform zero elimination,    */\n/*    and are recommended over their counterparts.  The procedure            */\n/*    fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on   */\n/*    processors that do not use the round-to-even tiebreaking rule) is      */\n/*    recommended over expansion_sum_zeroelim().  Each procedure has a       */\n/*    little note next to it (in the code below) that tells you whether or   */\n/*    not the output expansion may be the same array as one of the input     */\n/*    expansions.                                                            */\n/*                                                                           */\n/*                                                                           */\n/*  If you look around below, you'll also find macros for a bunch of         */\n/*    simple unrolled arithmetic operations, and procedures for printing     */\n/*    expansions (commented out because they don't work with all C           */\n/*    compilers) and for generating random floating-point numbers whose      */\n/*    significand bits are all random.  Most of the macros have undocumented */\n/*    requirements that certain of their parameters should not be the same   */\n/*    variable; for safety, better to make sure all the parameters are       */\n/*    distinct variables.  Feel free to send email to jrs@cs.cmu.edu if you  */\n/*    have questions.                                                        */\n/*                                                                           */\n/*****************************************************************************/\n\n#define REAL float\n\n/* Which of the following two methods of finding the absolute values is      */\n/*   fastest is compiler-dependent.  A few compilers can inline and optimize */\n/*   the fabs() call; but most will incur the overhead of a function call,   */\n/*   which is disastrously slow.  A faster way on IEEE machines might be to  */\n/*   mask the appropriate bit, but that's difficult to do in C.              */\n\n#define Absolute(a) fabsf(a)\n\n/* Many of the operations are broken up into two pieces, a main part that    */\n/*   performs an approximate operation, and a \"tail\" that computes the       */\n/*   roundoff error of that operation.                                       */\n/*                                                                           */\n/* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(),    */\n/*   Split(), and Two_Product() are all implemented as described in the      */\n/*   reference.  Each of these macros requires certain variables to be       */\n/*   defined in the calling routine.  The variables `bvirt', `c', `abig',    */\n/*   `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because   */\n/*   they store the result of an operation that may incur roundoff error.    */\n/*   The input parameter `x' (or the highest numbered `x_' parameter) must   */\n/*   also be declared `INEXACT'.                                             */\n\n#define Fast_Two_Sum_Tail(a, b, x, y)                                          \\\n    bvirt = x - a;                                                             \\\n    y = b - bvirt\n\n#define Fast_Two_Sum(a, b, x, y)                                               \\\n    x = (REAL)(a + b);                                                         \\\n    Fast_Two_Sum_Tail(a, b, x, y)\n\n#define Two_Sum_Tail(a, b, x, y)                                               \\\n    bvirt = (REAL)(x - a);                                                     \\\n    avirt = x - bvirt;                                                         \\\n    bround = b - bvirt;                                                        \\\n    around = a - avirt;                                                        \\\n    y = around + bround\n\n#define Two_Sum(a, b, x, y)                                                    \\\n    x = (REAL)(a + b);                                                         \\\n    Two_Sum_Tail(a, b, x, y)\n\n#define Two_Diff_Tail(a, b, x, y)                                              \\\n    bvirt = (REAL)(a - x);                                                     \\\n    avirt = x + bvirt;                                                         \\\n    bround = bvirt - b;                                                        \\\n    around = a - avirt;                                                        \\\n    y = around + bround\n\n#define Two_Diff(a, b, x, y)                                                   \\\n    x = (REAL)(a - b);                                                         \\\n    Two_Diff_Tail(a, b, x, y)\n\n#define Split(a, ahi, alo)                                                     \\\n    c = __fmul_rn(splitter, a);                                                \\\n    abig = (REAL)(c - a);                                                      \\\n    ahi = c - abig;                                                            \\\n    alo = a - ahi\n\n#define Two_Product_Tail(a, b, x, y)                                           \\\n    Split(a, ahi, alo);                                                        \\\n    Split(b, bhi, blo);                                                        \\\n    err1 = x - __fmul_rn(ahi, bhi);                                            \\\n    err2 = err1 - __fmul_rn(alo, bhi);                                         \\\n    err3 = err2 - __fmul_rn(ahi, blo);                                         \\\n    y = __fmul_rn(alo, blo) - err3\n\n#define Two_Product(a, b, x, y)                                                \\\n    x = __fmul_rn(a, b);                                                       \\\n    Two_Product_Tail(a, b, x, y)\n\n/* Two_Product_Presplit() is Two_Product() where one of the inputs has       */\n/*   already been split.  Avoids redundant splitting.                        */\n\n#define Two_Product_Presplit(a, b, bhi, blo, x, y)                             \\\n    x = __fmul_rn(a, b);                                                       \\\n    Split(a, ahi, alo);                                                        \\\n    err1 = x - __fmul_rn(ahi, bhi);                                            \\\n    err2 = err1 - __fmul_rn(alo, bhi);                                         \\\n    err3 = err2 - __fmul_rn(ahi, blo);                                         \\\n    y = __fmul_rn(alo, blo) - err3\n\n/* Two_Product_2Presplit() is Two_Product() where both of the inputs have    */\n/*   already been split.  Avoids redundant splitting.                        */\n\n#define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y)                  \\\n    x = __fmul_rn(a, b);                                                       \\\n    err1 = x - __fmul_rn(ahi, bhi);                                            \\\n    err2 = err1 - __fmul_rn(alo, bhi);                                         \\\n    err3 = err2 - __fmul_rn(ahi, blo);                                         \\\n    y = __fmul_rn(alo, blo) - err3\n\n/* Macros for summing expansions of various fixed lengths.  These are all    */\n/*   unrolled versions of Expansion_Sum().                                   */\n\n#define Two_One_Diff(a1, a0, b, x2, x1, x0)                                    \\\n    Two_Diff(a0, b, _i, x0);                                                   \\\n    Two_Sum(a1, _i, x2, x1)\n\n#define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0)                           \\\n    Two_One_Diff(a1, a0, b0, _j, _0, x0);                                      \\\n    Two_One_Diff(_j, _0, b1, x3, x2, x1)\n\n/* Macros for multiplying expansions of various fixed lengths.               */\n\n#define Two_One_Product(a1, a0, b, x3, x2, x1, x0)                             \\\n    Split(b, bhi, blo);                                                        \\\n    Two_Product_Presplit(a0, b, bhi, blo, _i, x0);                             \\\n    Two_Product_Presplit(a1, b, bhi, blo, _j, _0);                             \\\n    Two_Sum(_i, _0, _k, x1);                                                   \\\n    Fast_Two_Sum(_j, _k, x3, x2)\n\n#define Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0)        \\\n    Split(a0, a0hi, a0lo);                                                     \\\n    Split(b0, bhi, blo);                                                       \\\n    Two_Product_2Presplit(a0, a0hi, a0lo, b0, bhi, blo, _i, x0);               \\\n    Split(a1, a1hi, a1lo);                                                     \\\n    Two_Product_2Presplit(a1, a1hi, a1lo, b0, bhi, blo, _j, _0);               \\\n    Two_Sum(_i, _0, _k, _1);                                                   \\\n    Fast_Two_Sum(_j, _k, _l, _2);                                              \\\n    Split(b1, bhi, blo);                                                       \\\n    Two_Product_2Presplit(a0, a0hi, a0lo, b1, bhi, blo, _i, _0);               \\\n    Two_Sum(_1, _0, _k, x1);                                                   \\\n    Two_Sum(_2, _k, _j, _1);                                                   \\\n    Two_Sum(_l, _j, _m, _2);                                                   \\\n    Two_Product_2Presplit(a1, a1hi, a1lo, b1, bhi, blo, _j, _0);               \\\n    Two_Sum(_i, _0, _n, _0);                                                   \\\n    Two_Sum(_1, _0, _i, x2);                                                   \\\n    Two_Sum(_2, _i, _k, _1);                                                   \\\n    Two_Sum(_m, _k, _l, _2);                                                   \\\n    Two_Sum(_j, _n, _k, _0);                                                   \\\n    Two_Sum(_1, _0, _j, x3);                                                   \\\n    Two_Sum(_2, _j, _i, _1);                                                   \\\n    Two_Sum(_l, _i, _m, _2);                                                   \\\n    Two_Sum(_1, _k, _i, x4);                                                   \\\n    Two_Sum(_2, _i, _k, x5);                                                   \\\n    Two_Sum(_m, _k, x7, x6)\n\n/*****************************************************************************/\n/*                                                                           */\n/*  exactinit()   Initialize the variables used for exact arithmetic.        */\n/*                                                                           */\n/*  `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in   */\n/*  floating-point arithmetic.  `epsilon' bounds the relative roundoff       */\n/*  error.  It is used for floating-point error analysis.                    */\n/*                                                                           */\n/*  `splitter' is used to split floating-point numbers into two half-        */\n/*  length significands for exact multiplication.                            */\n/*                                                                           */\n/*  I imagine that a highly optimizing compiler might be too smart for its   */\n/*  own good, and somehow cause this routine to fail, if it pretends that    */\n/*  floating-point arithmetic is too much like real arithmetic.              */\n/*                                                                           */\n/*  Don't change this routine unless you fully understand it.                */\n/*                                                                           */\n/*****************************************************************************/\n\nconstexpr REAL splitter = 4097;\n\nconstexpr REAL exactinit() noexcept {\n    REAL half = 0.5;\n    REAL epsilon = 1.0;\n    REAL check = 1.0;\n    REAL lastcheck = 1.0;\n\n    /* Repeatedly divide `epsilon' by two until it is too small to add to    */\n    /*   one without causing roundoff.  (Also check if the sum is equal to   */\n    /*   the previous sum, for machines that round up instead of using exact */\n    /*   rounding.  Not that this library will work on such machines anyway. */\n    do {\n        lastcheck = check;\n        epsilon *= half;\n        check = 1.0 + epsilon;\n    } while ((check != 1.0) && (check != lastcheck));\n\n    return epsilon;\n}\n\nconstexpr REAL epsilon = exactinit();\nconstexpr REAL resulterrbound = (3.0 + 8.0 * epsilon) * epsilon;\nconstexpr REAL ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon;\nconstexpr REAL ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon;\nconstexpr REAL ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon;\nconstexpr REAL o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon;\nconstexpr REAL o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon;\nconstexpr REAL o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon;\nconstexpr REAL iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon;\nconstexpr REAL iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon;\nconstexpr REAL iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon;\nconstexpr REAL isperrboundA = (16.0 + 224.0 * epsilon) * epsilon;\nconstexpr REAL isperrboundB = (5.0 + 72.0 * epsilon) * epsilon;\nconstexpr REAL isperrboundC = (71.0 + 1408.0 * epsilon) * epsilon * epsilon;\n\n/*****************************************************************************/\n/*                                                                           */\n/*  scale_expansion_zeroelim()   Multiply an expansion by a scalar,          */\n/*                               eliminating zero components from the        */\n/*                               output expansion.                           */\n/*                                                                           */\n/*  Sets h = be.  See either version of my paper for details.                */\n/*                                                                           */\n/*  Maintains the nonoverlapping property.  If round-to-even is used (as     */\n/*  with IEEE 754), maintains the strongly nonoverlapping and nonadjacent    */\n/*  properties as well.  (That is, if e has one of these properties, so      */\n/*  will h.)                                                                 */\n/*                                                                           */\n/*****************************************************************************/\n\n__noinline__ inline __device__ int\nscale_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h) {\n    /* e and h cannot be the same. */\n    REAL Q, sum;\n    REAL hh;\n    REAL product1;\n    REAL product0;\n    int eindex, hindex;\n    REAL enow;\n    REAL bvirt;\n    REAL avirt, bround, around;\n    REAL c;\n    REAL abig;\n    REAL ahi, alo, bhi, blo;\n    REAL err1, err2, err3;\n\n    Split(b, bhi, blo);\n    Two_Product_Presplit(e[0], b, bhi, blo, Q, hh);\n    hindex = 0;\n    if (hh != 0) {\n        h[hindex++] = hh;\n    }\n    for (eindex = 1; eindex < elen; eindex++) {\n        enow = e[eindex];\n        Two_Product_Presplit(enow, b, bhi, blo, product1, product0);\n        Two_Sum(Q, product0, sum, hh);\n        if (hh != 0) {\n            h[hindex++] = hh;\n        }\n        Fast_Two_Sum(product1, sum, Q, hh);\n        if (hh != 0) {\n            h[hindex++] = hh;\n        }\n    }\n    if ((Q != 0.0) || (hindex == 0)) {\n        h[hindex++] = Q;\n    }\n    return hindex;\n}\n\n/*****************************************************************************/\n/*                                                                           */\n/*  fast_expansion_sum_zeroelim()   Sum two expansions, eliminating zero     */\n/*                                  components from the output expansion.    */\n/*                                                                           */\n/*  Sets h = e + f.  See the long version of my paper for details.           */\n/*                                                                           */\n/*  If round-to-even is used (as with IEEE 754), maintains the strongly      */\n/*  nonoverlapping property.  (That is, if e is strongly nonoverlapping, h   */\n/*  will be also.)  Does NOT maintain the nonoverlapping or nonadjacent      */\n/*  properties.                                                              */\n/*                                                                           */\n/*****************************************************************************/\n\n__noinline__ inline __device__ int\nfast_expansion_sum_zeroelim(int elen, REAL *e, int flen, REAL *f, REAL *h) {\n    /* h cannot be e or f. */\n    REAL Q;\n    REAL Qnew;\n    REAL hh;\n    REAL bvirt;\n    REAL avirt, bround, around;\n    int eindex, findex, hindex;\n    REAL enow, fnow;\n\n    enow = e[0];\n    fnow = f[0];\n    eindex = findex = 0;\n    if ((fnow > enow) == (fnow > -enow)) {\n        Q = enow;\n        enow = e[++eindex];\n    } else {\n        Q = fnow;\n        fnow = f[++findex];\n    }\n    hindex = 0;\n    if ((eindex < elen) && (findex < flen)) {\n        if ((fnow > enow) == (fnow > -enow)) {\n            Fast_Two_Sum(enow, Q, Qnew, hh);\n            enow = e[++eindex];\n        } else {\n            Fast_Two_Sum(fnow, Q, Qnew, hh);\n            fnow = f[++findex];\n        }\n        Q = Qnew;\n        if (hh != 0.0) {\n            h[hindex++] = hh;\n        }\n        while ((eindex < elen) && (findex < flen)) {\n            if ((fnow > enow) == (fnow > -enow)) {\n                Two_Sum(Q, enow, Qnew, hh);\n                enow = e[++eindex];\n            } else {\n                Two_Sum(Q, fnow, Qnew, hh);\n                fnow = f[++findex];\n            }\n            Q = Qnew;\n            if (hh != 0.0) {\n                h[hindex++] = hh;\n            }\n        }\n    }\n    while (eindex < elen) {\n        Two_Sum(Q, enow, Qnew, hh);\n        enow = e[++eindex];\n        Q = Qnew;\n        if (hh != 0.0) {\n            h[hindex++] = hh;\n        }\n    }\n    while (findex < flen) {\n        Two_Sum(Q, fnow, Qnew, hh);\n        fnow = f[++findex];\n        Q = Qnew;\n        if (hh != 0.0) {\n            h[hindex++] = hh;\n        }\n    }\n    if ((Q != 0.0) || (hindex == 0)) {\n        h[hindex++] = Q;\n    }\n    return hindex;\n}\n\n/*****************************************************************************/\n/*                                                                           */\n/*  estimate()   Produce a one-word estimate of an expansion's value.        */\n/*                                                                           */\n/*  See either version of my paper for details.                              */\n/*                                                                           */\n/*****************************************************************************/\n\n__forceinline__ __device__ REAL estimate(int elen, REAL *e) {\n    REAL Q;\n    int eindex;\n\n    Q = e[0];\n    for (eindex = 1; eindex < elen; eindex++) {\n        Q += e[eindex];\n    }\n    return Q;\n}\n\nenum class PredicateResult {\n    Inside,\n    Outside,\n    Ambiguous,\n};\n\n/*****************************************************************************/\n/*                                                                           */\n/*  orient3dfast()   Approximate 3D orientation test.  Nonrobust.            */\n/*  orient3dexact()   Exact 3D orientation test.  Robust.                    */\n/*  orient3dslow()   Another exact 3D orientation test.  Robust.             */\n/*  orient3d()   Adaptive exact 3D orientation test.  Robust.                */\n/*                                                                           */\n/*               Return a positive value if the point pd lies below the      */\n/*               plane passing through pa, pb, and pc; \"below\" is defined so */\n/*               that pa, pb, and pc appear in counterclockwise order when   */\n/*               viewed from above the plane.  Returns a negative value if   */\n/*               pd lies above the plane.  Returns zero if the points are    */\n/*               coplanar.  The result is also a rough approximation of six  */\n/*               times the signed volume of the tetrahedron defined by the   */\n/*               four points.                                                */\n/*                                                                           */\n/*  Only the first and last routine should be used; the middle two are for   */\n/*  timings.                                                                 */\n/*                                                                           */\n/*  The last three use exact arithmetic to ensure a correct answer.  The     */\n/*  result returned is the determinant of a matrix.  In orient3d() only,     */\n/*  this determinant is computed adaptively, in the sense that exact         */\n/*  arithmetic is used only to the degree it is needed to ensure that the    */\n/*  returned value has the correct sign.  Hence, orient3d() is usually quite */\n/*  fast, but will run more slowly when the input points are coplanar or     */\n/*  nearly so.                                                               */\n/*                                                                           */\n/*****************************************************************************/\n\n__forceinline__ __device__ PredicateResult orient3dconservative(\n    const Vec3f &pa, const Vec3f &pb, const Vec3f &pc, const Vec3f &pd) {\n    REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz;\n    REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;\n    REAL det;\n    REAL permanent, errbound;\n\n    adx = pa[0] - pd[0];\n    bdx = pb[0] - pd[0];\n    cdx = pc[0] - pd[0];\n    ady = pa[1] - pd[1];\n    bdy = pb[1] - pd[1];\n    cdy = pc[1] - pd[1];\n    adz = pa[2] - pd[2];\n    bdz = pb[2] - pd[2];\n    cdz = pc[2] - pd[2];\n\n    bdxcdy = __fmul_rn(bdx, cdy);\n    cdxbdy = __fmul_rn(cdx, bdy);\n\n    cdxady = __fmul_rn(cdx, ady);\n    adxcdy = __fmul_rn(adx, cdy);\n\n    adxbdy = __fmul_rn(adx, bdy);\n    bdxady = __fmul_rn(bdx, ady);\n\n    det = __fmul_rn(adz, (bdxcdy - cdxbdy)) +\n          __fmul_rn(bdz, (cdxady - adxcdy)) + __fmul_rn(cdz, (adxbdy - bdxady));\n\n    permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adz) +\n                (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdz) +\n                (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdz);\n    errbound = __fmul_rn(o3derrboundA, permanent);\n\n    if (det > -errbound) {\n        return PredicateResult::Inside;\n    } else {\n        return PredicateResult::Outside;\n    }\n}\n\n__forceinline__ __device__ REAL orient3dadapt(const Vec3f &pa,\n                                              const Vec3f &pb,\n                                              const Vec3f &pc,\n                                              const Vec3f &pd,\n                                              float permanent) {\n    REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz;\n    REAL det, errbound;\n\n    REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;\n    REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;\n    REAL bc[4], ca[4], ab[4];\n    REAL bc3, ca3, ab3;\n    REAL adet[8], bdet[8], cdet[8];\n    int alen, blen, clen;\n    REAL abdet[16];\n    int ablen;\n    REAL *finnow, *finother, *finswap;\n    REAL fin1[192], fin2[192];\n    int finlength;\n\n    REAL adxtail, bdxtail, cdxtail;\n    REAL adytail, bdytail, cdytail;\n    REAL adztail, bdztail, cdztail;\n    REAL at_blarge, at_clarge;\n    REAL bt_clarge, bt_alarge;\n    REAL ct_alarge, ct_blarge;\n    REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4];\n    int at_blen, at_clen, bt_clen, bt_alen, ct_alen, ct_blen;\n    REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1;\n    REAL adxt_cdy1, adxt_bdy1, bdxt_ady1;\n    REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0;\n    REAL adxt_cdy0, adxt_bdy0, bdxt_ady0;\n    REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1;\n    REAL adyt_cdx1, adyt_bdx1, bdyt_adx1;\n    REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0;\n    REAL adyt_cdx0, adyt_bdx0, bdyt_adx0;\n    REAL bct[8], cat[8], abt[8];\n    int bctlen, catlen, abtlen;\n    REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1;\n    REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1;\n    REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0;\n    REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0;\n    REAL u[4], v[12], w[16];\n    REAL u3;\n    int vlength, wlength;\n    REAL negate;\n\n    REAL bvirt;\n    REAL avirt, bround, around;\n    REAL c;\n    REAL abig;\n    REAL ahi, alo, bhi, blo;\n    REAL err1, err2, err3;\n    REAL _i, _j, _k;\n    REAL _0;\n\n    adx = (REAL)(pa[0] - pd[0]);\n    bdx = (REAL)(pb[0] - pd[0]);\n    cdx = (REAL)(pc[0] - pd[0]);\n    ady = (REAL)(pa[1] - pd[1]);\n    bdy = (REAL)(pb[1] - pd[1]);\n    cdy = (REAL)(pc[1] - pd[1]);\n    adz = (REAL)(pa[2] - pd[2]);\n    bdz = (REAL)(pb[2] - pd[2]);\n    cdz = (REAL)(pc[2] - pd[2]);\n\n    Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);\n    Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);\n    Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);\n    bc[3] = bc3;\n    alen = scale_expansion_zeroelim(4, bc, adz, adet);\n\n    Two_Product(cdx, ady, cdxady1, cdxady0);\n    Two_Product(adx, cdy, adxcdy1, adxcdy0);\n    Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);\n    ca[3] = ca3;\n    blen = scale_expansion_zeroelim(4, ca, bdz, bdet);\n\n    Two_Product(adx, bdy, adxbdy1, adxbdy0);\n    Two_Product(bdx, ady, bdxady1, bdxady0);\n    Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);\n    ab[3] = ab3;\n    clen = scale_expansion_zeroelim(4, ab, cdz, cdet);\n\n    ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);\n    finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);\n\n    det = estimate(finlength, fin1);\n    errbound = o3derrboundB * permanent;\n    if ((det >= errbound) || (-det >= errbound)) {\n        return det;\n    }\n\n    Two_Diff_Tail(pa[0], pd[0], adx, adxtail);\n    Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);\n    Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);\n    Two_Diff_Tail(pa[1], pd[1], ady, adytail);\n    Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);\n    Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);\n    Two_Diff_Tail(pa[2], pd[2], adz, adztail);\n    Two_Diff_Tail(pb[2], pd[2], bdz, bdztail);\n    Two_Diff_Tail(pc[2], pd[2], cdz, cdztail);\n\n    if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) &&\n        (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0) &&\n        (adztail == 0.0) && (bdztail == 0.0) && (cdztail == 0.0)) {\n        return det;\n    }\n\n    errbound = __fmul_rn(o3derrboundC, permanent) +\n               __fmul_rn(resulterrbound, Absolute(det));\n    det += (__fmul_rn(adz,\n                      ((__fmul_rn(bdx, cdytail) + __fmul_rn(cdy, bdxtail)) -\n                       (__fmul_rn(bdy, cdxtail) + __fmul_rn(cdx, bdytail)))) +\n            __fmul_rn(adztail, (__fmul_rn(bdx, cdy) - __fmul_rn(bdy, cdx)))) +\n           (__fmul_rn(bdz,\n                      ((__fmul_rn(cdx, adytail) + __fmul_rn(ady, cdxtail)) -\n                       (__fmul_rn(cdy, adxtail) + __fmul_rn(adx, cdytail)))) +\n            __fmul_rn(bdztail, (__fmul_rn(cdx, ady) - __fmul_rn(cdy, adx)))) +\n           (__fmul_rn(cdz,\n                      ((__fmul_rn(adx, bdytail) + __fmul_rn(bdy, adxtail)) -\n                       (__fmul_rn(ady, bdxtail) + __fmul_rn(bdx, adytail)))) +\n            __fmul_rn(cdztail, (__fmul_rn(adx, bdy) - __fmul_rn(ady, bdx))));\n    if ((det >= errbound) || (-det >= errbound)) {\n        return det;\n    }\n\n    finnow = fin1;\n    finother = fin2;\n\n    if (adxtail == 0.0) {\n        if (adytail == 0.0) {\n            at_b[0] = 0.0;\n            at_blen = 1;\n            at_c[0] = 0.0;\n            at_clen = 1;\n        } else {\n            negate = -adytail;\n            Two_Product(negate, bdx, at_blarge, at_b[0]);\n            at_b[1] = at_blarge;\n            at_blen = 2;\n            Two_Product(adytail, cdx, at_clarge, at_c[0]);\n            at_c[1] = at_clarge;\n            at_clen = 2;\n        }\n    } else {\n        if (adytail == 0.0) {\n            Two_Product(adxtail, bdy, at_blarge, at_b[0]);\n            at_b[1] = at_blarge;\n            at_blen = 2;\n            negate = -adxtail;\n            Two_Product(negate, cdy, at_clarge, at_c[0]);\n            at_c[1] = at_clarge;\n            at_clen = 2;\n        } else {\n            Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0);\n            Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0);\n            Two_Two_Diff(adxt_bdy1,\n                         adxt_bdy0,\n                         adyt_bdx1,\n                         adyt_bdx0,\n                         at_blarge,\n                         at_b[2],\n                         at_b[1],\n                         at_b[0]);\n            at_b[3] = at_blarge;\n            at_blen = 4;\n            Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0);\n            Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0);\n            Two_Two_Diff(adyt_cdx1,\n                         adyt_cdx0,\n                         adxt_cdy1,\n                         adxt_cdy0,\n                         at_clarge,\n                         at_c[2],\n                         at_c[1],\n                         at_c[0]);\n            at_c[3] = at_clarge;\n            at_clen = 4;\n        }\n    }\n    if (bdxtail == 0.0) {\n        if (bdytail == 0.0) {\n            bt_c[0] = 0.0;\n            bt_clen = 1;\n            bt_a[0] = 0.0;\n            bt_alen = 1;\n        } else {\n            negate = -bdytail;\n            Two_Product(negate, cdx, bt_clarge, bt_c[0]);\n            bt_c[1] = bt_clarge;\n            bt_clen = 2;\n            Two_Product(bdytail, adx, bt_alarge, bt_a[0]);\n            bt_a[1] = bt_alarge;\n            bt_alen = 2;\n        }\n    } else {\n        if (bdytail == 0.0) {\n            Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]);\n            bt_c[1] = bt_clarge;\n            bt_clen = 2;\n            negate = -bdxtail;\n            Two_Product(negate, ady, bt_alarge, bt_a[0]);\n            bt_a[1] = bt_alarge;\n            bt_alen = 2;\n        } else {\n            Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0);\n            Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0);\n            Two_Two_Diff(bdxt_cdy1,\n                         bdxt_cdy0,\n                         bdyt_cdx1,\n                         bdyt_cdx0,\n                         bt_clarge,\n                         bt_c[2],\n                         bt_c[1],\n                         bt_c[0]);\n            bt_c[3] = bt_clarge;\n            bt_clen = 4;\n            Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0);\n            Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0);\n            Two_Two_Diff(bdyt_adx1,\n                         bdyt_adx0,\n                         bdxt_ady1,\n                         bdxt_ady0,\n                         bt_alarge,\n                         bt_a[2],\n                         bt_a[1],\n                         bt_a[0]);\n            bt_a[3] = bt_alarge;\n            bt_alen = 4;\n        }\n    }\n    if (cdxtail == 0.0) {\n        if (cdytail == 0.0) {\n            ct_a[0] = 0.0;\n            ct_alen = 1;\n            ct_b[0] = 0.0;\n            ct_blen = 1;\n        } else {\n            negate = -cdytail;\n            Two_Product(negate, adx, ct_alarge, ct_a[0]);\n            ct_a[1] = ct_alarge;\n            ct_alen = 2;\n            Two_Product(cdytail, bdx, ct_blarge, ct_b[0]);\n            ct_b[1] = ct_blarge;\n            ct_blen = 2;\n        }\n    } else {\n        if (cdytail == 0.0) {\n            Two_Product(cdxtail, ady, ct_alarge, ct_a[0]);\n            ct_a[1] = ct_alarge;\n            ct_alen = 2;\n            negate = -cdxtail;\n            Two_Product(negate, bdy, ct_blarge, ct_b[0]);\n            ct_b[1] = ct_blarge;\n            ct_blen = 2;\n        } else {\n            Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0);\n            Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0);\n            Two_Two_Diff(cdxt_ady1,\n                         cdxt_ady0,\n                         cdyt_adx1,\n                         cdyt_adx0,\n                         ct_alarge,\n                         ct_a[2],\n                         ct_a[1],\n                         ct_a[0]);\n            ct_a[3] = ct_alarge;\n            ct_alen = 4;\n            Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0);\n            Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0);\n            Two_Two_Diff(cdyt_bdx1,\n                         cdyt_bdx0,\n                         cdxt_bdy1,\n                         cdxt_bdy0,\n                         ct_blarge,\n                         ct_b[2],\n                         ct_b[1],\n                         ct_b[0]);\n            ct_b[3] = ct_blarge;\n            ct_blen = 4;\n        }\n    }\n\n    bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct);\n    wlength = scale_expansion_zeroelim(bctlen, bct, adz, w);\n    finlength =\n        fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, finother);\n    finswap = finnow;\n    finnow = finother;\n    finother = finswap;\n\n    catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat);\n    wlength = scale_expansion_zeroelim(catlen, cat, bdz, w);\n    finlength =\n        fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, finother);\n    finswap = finnow;\n    finnow = finother;\n    finother = finswap;\n\n    abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt);\n    wlength = scale_expansion_zeroelim(abtlen, abt, cdz, w);\n    finlength =\n        fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, finother);\n    finswap = finnow;\n    finnow = finother;\n    finother = finswap;\n\n    if (adztail != 0.0) {\n        vlength = scale_expansion_zeroelim(4, bc, adztail, v);\n        finlength = fast_expansion_sum_zeroelim(\n            finlength, finnow, vlength, v, finother);\n        finswap = finnow;\n        finnow = finother;\n        finother = finswap;\n    }\n    if (bdztail != 0.0) {\n        vlength = scale_expansion_zeroelim(4, ca, bdztail, v);\n        finlength = fast_expansion_sum_zeroelim(\n            finlength, finnow, vlength, v, finother);\n        finswap = finnow;\n        finnow = finother;\n        finother = finswap;\n    }\n    if (cdztail != 0.0) {\n        vlength = scale_expansion_zeroelim(4, ab, cdztail, v);\n        finlength = fast_expansion_sum_zeroelim(\n            finlength, finnow, vlength, v, finother);\n        finswap = finnow;\n        finnow = finother;\n        finother = finswap;\n    }\n\n    if (adxtail != 0.0) {\n        if (bdytail != 0.0) {\n            Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0);\n            Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdz, u3, u[2], u[1], u[0]);\n            u[3] = u3;\n            finlength =\n                fast_expansion_sum_zeroelim(finlength, finnow, 4, u, finother);\n            finswap = finnow;\n            finnow = finother;\n            finother = finswap;\n            if (cdztail != 0.0) {\n                Two_One_Product(\n                    adxt_bdyt1, adxt_bdyt0, cdztail, u3, u[2], u[1], u[0]);\n                u[3] = u3;\n                finlength = fast_expansion_sum_zeroelim(\n                    finlength, finnow, 4, u, finother);\n                finswap = finnow;\n                finnow = finother;\n                finother = finswap;\n            }\n        }\n        if (cdytail != 0.0) {\n            negate = -adxtail;\n            Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0);\n            Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdz, u3, u[2], u[1], u[0]);\n            u[3] = u3;\n            finlength =\n                fast_expansion_sum_zeroelim(finlength, finnow, 4, u, finother);\n            finswap = finnow;\n            finnow = finother;\n            finother = finswap;\n            if (bdztail != 0.0) {\n                Two_One_Product(\n                    adxt_cdyt1, adxt_cdyt0, bdztail, u3, u[2], u[1], u[0]);\n                u[3] = u3;\n                finlength = fast_expansion_sum_zeroelim(\n                    finlength, finnow, 4, u, finother);\n                finswap = finnow;\n                finnow = finother;\n                finother = finswap;\n            }\n        }\n    }\n    if (bdxtail != 0.0) {\n        if (cdytail != 0.0) {\n            Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0);\n            Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adz, u3, u[2], u[1], u[0]);\n            u[3] = u3;\n            finlength =\n                fast_expansion_sum_zeroelim(finlength, finnow, 4, u, finother);\n            finswap = finnow;\n            finnow = finother;\n            finother = finswap;\n            if (adztail != 0.0) {\n                Two_One_Product(\n                    bdxt_cdyt1, bdxt_cdyt0, adztail, u3, u[2], u[1], u[0]);\n                u[3] = u3;\n                finlength = fast_expansion_sum_zeroelim(\n                    finlength, finnow, 4, u, finother);\n                finswap = finnow;\n                finnow = finother;\n                finother = finswap;\n            }\n        }\n        if (adytail != 0.0) {\n            negate = -bdxtail;\n            Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0);\n            Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdz, u3, u[2], u[1], u[0]);\n            u[3] = u3;\n            finlength =\n                fast_expansion_sum_zeroelim(finlength, finnow, 4, u, finother);\n            finswap = finnow;\n            finnow = finother;\n            finother = finswap;\n            if (cdztail != 0.0) {\n                Two_One_Product(\n                    bdxt_adyt1, bdxt_adyt0, cdztail, u3, u[2], u[1], u[0]);\n                u[3] = u3;\n                finlength = fast_expansion_sum_zeroelim(\n                    finlength, finnow, 4, u, finother);\n                finswap = finnow;\n                finnow = finother;\n                finother = finswap;\n            }\n        }\n    }\n    if (cdxtail != 0.0) {\n        if (adytail != 0.0) {\n            Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0);\n            Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdz, u3, u[2], u[1], u[0]);\n            u[3] = u3;\n            finlength =\n                fast_expansion_sum_zeroelim(finlength, finnow, 4, u, finother);\n            finswap = finnow;\n            finnow = finother;\n            finother = finswap;\n            if (bdztail != 0.0) {\n                Two_One_Product(\n                    cdxt_adyt1, cdxt_adyt0, bdztail, u3, u[2], u[1], u[0]);\n                u[3] = u3;\n                finlength = fast_expansion_sum_zeroelim(\n                    finlength, finnow, 4, u, finother);\n                finswap = finnow;\n                finnow = finother;\n                finother = finswap;\n            }\n        }\n        if (bdytail != 0.0) {\n            negate = -cdxtail;\n            Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0);\n            Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adz, u3, u[2], u[1], u[0]);\n            u[3] = u3;\n            finlength =\n                fast_expansion_sum_zeroelim(finlength, finnow, 4, u, finother);\n            finswap = finnow;\n            finnow = finother;\n            finother = finswap;\n            if (adztail != 0.0) {\n                Two_One_Product(\n                    cdxt_bdyt1, cdxt_bdyt0, adztail, u3, u[2], u[1], u[0]);\n                u[3] = u3;\n                finlength = fast_expansion_sum_zeroelim(\n                    finlength, finnow, 4, u, finother);\n                finswap = finnow;\n                finnow = finother;\n                finother = finswap;\n            }\n        }\n    }\n\n    if (adztail != 0.0) {\n        wlength = scale_expansion_zeroelim(bctlen, bct, adztail, w);\n        finlength = fast_expansion_sum_zeroelim(\n            finlength, finnow, wlength, w, finother);\n        finswap = finnow;\n        finnow = finother;\n        finother = finswap;\n    }\n    if (bdztail != 0.0) {\n        wlength = scale_expansion_zeroelim(catlen, cat, bdztail, w);\n        finlength = fast_expansion_sum_zeroelim(\n            finlength, finnow, wlength, w, finother);\n        finswap = finnow;\n        finnow = finother;\n        finother = finswap;\n    }\n    if (cdztail != 0.0) {\n        wlength = scale_expansion_zeroelim(abtlen, abt, cdztail, w);\n        finlength = fast_expansion_sum_zeroelim(\n            finlength, finnow, wlength, w, finother);\n        finswap = finnow;\n        finnow = finother;\n        finother = finswap;\n    }\n\n    return finnow[finlength - 1];\n}\n\n__forceinline__ __device__ PredicateResult orient3d(const Vec3f &pa,\n                                                    const Vec3f &pb,\n                                                    const Vec3f &pc,\n                                                    const Vec3f &pd) {\n    REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz;\n    REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;\n    REAL det;\n    REAL permanent, errbound;\n\n    adx = pa[0] - pd[0];\n    bdx = pb[0] - pd[0];\n    cdx = pc[0] - pd[0];\n    ady = pa[1] - pd[1];\n    bdy = pb[1] - pd[1];\n    cdy = pc[1] - pd[1];\n    adz = pa[2] - pd[2];\n    bdz = pb[2] - pd[2];\n    cdz = pc[2] - pd[2];\n\n    bdxcdy = __fmul_rn(bdx, cdy);\n    cdxbdy = __fmul_rn(cdx, bdy);\n\n    cdxady = __fmul_rn(cdx, ady);\n    adxcdy = __fmul_rn(adx, cdy);\n\n    adxbdy = __fmul_rn(adx, bdy);\n    bdxady = __fmul_rn(bdx, ady);\n\n    det = __fmul_rn(adz, (bdxcdy - cdxbdy)) +\n          __fmul_rn(bdz, (cdxady - adxcdy)) + __fmul_rn(cdz, (adxbdy - bdxady));\n\n    permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adz) +\n                (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdz) +\n                (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdz);\n    errbound = __fmul_rn(o3derrboundA, permanent);\n\n    if (!((det > errbound) || (-det > errbound))) {\n        det = orient3dadapt(pa, pb, pc, pd, permanent);\n    }\n\n    if (det > 0) {\n        return PredicateResult::Inside;\n    } else if (det < 0) {\n        return PredicateResult::Outside;\n    } else {\n        return PredicateResult::Ambiguous;\n    }\n}\n\n/*****************************************************************************/\n/*                                                                           */\n/*  inspherefast()   Approximate 3D insphere test.  Nonrobust.               */\n/*  insphereexact()   Exact 3D insphere test.  Robust.                       */\n/*  insphereslow()   Another exact 3D insphere test.  Robust.                */\n/*  insphere()   Adaptive exact 3D insphere test.  Robust.                   */\n/*                                                                           */\n/*               Return a positive value if the point pe lies inside the     */\n/*               sphere passing through pa, pb, pc, and pd; a negative value */\n/*               if it lies outside; and zero if the five points are         */\n/*               cospherical.  The points pa, pb, pc, and pd must be ordered */\n/*               so that they have a positive orientation (as defined by     */\n/*               orient3d()), or the sign of the result will be reversed.    */\n/*                                                                           */\n/*  Only the first and last routine should be used; the middle two are for   */\n/*  timings.                                                                 */\n/*                                                                           */\n/*  The last three use exact arithmetic to ensure a correct answer.  The     */\n/*  result returned is the determinant of a matrix.  In insphere() only,     */\n/*  this determinant is computed adaptively, in the sense that exact         */\n/*  arithmetic is used only to the degree it is needed to ensure that the    */\n/*  returned value has the correct sign.  Hence, insphere() is usually quite */\n/*  fast, but will run more slowly when the input points are cospherical or  */\n/*  nearly so.                                                               */\n/*                                                                           */\n/*****************************************************************************/\n\ninline __device__ PredicateResult insphereconservative(const Vec3f &pa,\n                                                       const Vec3f &pb,\n                                                       const Vec3f &pc,\n                                                       const Vec3f &pd,\n                                                       const Vec3f &pe) {\n    REAL aex, bex, cex, dex;\n    REAL aey, bey, cey, dey;\n    REAL aez, bez, cez, dez;\n    REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey;\n    REAL aexcey, cexaey, bexdey, dexbey;\n    REAL alift, blift, clift, dlift;\n    REAL ab, bc, cd, da, ac, bd;\n    REAL abc, bcd, cda, dab;\n    REAL aezplus, bezplus, cezplus, dezplus;\n    REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus;\n    REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus;\n    REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus;\n    REAL det;\n    REAL permanent, errbound;\n\n    aex = pa[0] - pe[0];\n    bex = pb[0] - pe[0];\n    cex = pc[0] - pe[0];\n    dex = pd[0] - pe[0];\n    aey = pa[1] - pe[1];\n    bey = pb[1] - pe[1];\n    cey = pc[1] - pe[1];\n    dey = pd[1] - pe[1];\n    aez = pa[2] - pe[2];\n    bez = pb[2] - pe[2];\n    cez = pc[2] - pe[2];\n    dez = pd[2] - pe[2];\n\n    aexbey = __fmul_rn(aex, bey);\n    bexaey = __fmul_rn(bex, aey);\n    ab = aexbey - bexaey;\n    bexcey = __fmul_rn(bex, cey);\n    cexbey = __fmul_rn(cex, bey);\n    bc = bexcey - cexbey;\n    cexdey = __fmul_rn(cex, dey);\n    dexcey = __fmul_rn(dex, cey);\n    cd = cexdey - dexcey;\n    dexaey = __fmul_rn(dex, aey);\n    aexdey = __fmul_rn(aex, dey);\n    da = dexaey - aexdey;\n\n    aexcey = __fmul_rn(aex, cey);\n    cexaey = __fmul_rn(cex, aey);\n    ac = aexcey - cexaey;\n    bexdey = __fmul_rn(bex, dey);\n    dexbey = __fmul_rn(dex, bey);\n    bd = bexdey - dexbey;\n\n    abc = __fmul_rn(aez, bc) - __fmul_rn(bez, ac) + __fmul_rn(cez, ab);\n    bcd = __fmul_rn(bez, cd) - __fmul_rn(cez, bd) + __fmul_rn(dez, bc);\n    cda = __fmul_rn(cez, da) + __fmul_rn(dez, ac) + __fmul_rn(aez, cd);\n    dab = __fmul_rn(dez, ab) + __fmul_rn(aez, bd) + __fmul_rn(bez, da);\n\n    alift = __fmul_rn(aex, aex) + __fmul_rn(aey, aey) + __fmul_rn(aez, aez);\n    blift = __fmul_rn(bex, bex) + __fmul_rn(bey, bey) + __fmul_rn(bez, bez);\n    clift = __fmul_rn(cex, cex) + __fmul_rn(cey, cey) + __fmul_rn(cez, cez);\n    dlift = __fmul_rn(dex, dex) + __fmul_rn(dey, dey) + __fmul_rn(dez, dez);\n\n    det = (__fmul_rn(dlift, abc) - __fmul_rn(clift, dab)) +\n          (__fmul_rn(blift, cda) - __fmul_rn(alift, bcd));\n\n    aezplus = Absolute(aez);\n    bezplus = Absolute(bez);\n    cezplus = Absolute(cez);\n    dezplus = Absolute(dez);\n    aexbeyplus = Absolute(aexbey);\n    bexaeyplus = Absolute(bexaey);\n    bexceyplus = Absolute(bexcey);\n    cexbeyplus = Absolute(cexbey);\n    cexdeyplus = Absolute(cexdey);\n    dexceyplus = Absolute(dexcey);\n    dexaeyplus = Absolute(dexaey);\n    aexdeyplus = Absolute(aexdey);\n    aexceyplus = Absolute(aexcey);\n    cexaeyplus = Absolute(cexaey);\n    bexdeyplus = Absolute(bexdey);\n    dexbeyplus = Absolute(dexbey);\n    permanent = __fmul_rn((__fmul_rn((cexdeyplus + dexceyplus), bezplus) +\n                           __fmul_rn((dexbeyplus + bexdeyplus), cezplus) +\n                           __fmul_rn((bexceyplus + cexbeyplus), dezplus)),\n                          alift) +\n                __fmul_rn((__fmul_rn((dexaeyplus + aexdeyplus), cezplus) +\n                           __fmul_rn((aexceyplus + cexaeyplus), dezplus) +\n                           __fmul_rn((cexdeyplus + dexceyplus), aezplus)),\n                          blift) +\n                __fmul_rn((__fmul_rn((aexbeyplus + bexaeyplus), dezplus) +\n                           __fmul_rn((bexdeyplus + dexbeyplus), aezplus) +\n                           __fmul_rn((dexaeyplus + aexdeyplus), bezplus)),\n                          clift) +\n                __fmul_rn((__fmul_rn((bexceyplus + cexbeyplus), aezplus) +\n                           __fmul_rn((cexaeyplus + aexceyplus), bezplus) +\n                           __fmul_rn((aexbeyplus + bexaeyplus), cezplus)),\n                          dlift);\n    errbound = __fmul_rn(isperrboundA, permanent);\n\n    if (det > -errbound) {\n        return PredicateResult::Inside;\n    } else {\n        return PredicateResult::Outside;\n    }\n}\n\nstruct InSphereExactStorage {\n    REAL axby1, bxcy1, cxdy1, dxey1, exay1;\n    REAL bxay1, cxby1, dxcy1, exdy1, axey1;\n    REAL axcy1, bxdy1, cxey1, dxay1, exby1;\n    REAL cxay1, dxby1, excy1, axdy1, bxey1;\n    REAL axby0, bxcy0, cxdy0, dxey0, exay0;\n    REAL bxay0, cxby0, dxcy0, exdy0, axey0;\n    REAL axcy0, bxdy0, cxey0, dxay0, exby0;\n    REAL cxay0, dxby0, excy0, axdy0, bxey0;\n    REAL ab[4], bc[4], cd[4], de[4], ea[4];\n    REAL ac[4], bd[4], ce[4], da[4], eb[4];\n    REAL temp8a[8], temp8b[8], temp16[16];\n    REAL abc[24], bcd[24], cde[24], dea[24], eab[24];\n    REAL abd[24], bce[24], cda[24], deb[24], eac[24];\n    REAL temp48a[48], temp48b[48];\n    REAL abcd[96], bcde[96], cdea[96], deab[96], eabc[96];\n    REAL temp192[192];\n    REAL det384x[384], det384y[384], det384z[384];\n    REAL detxy[768];\n    REAL adet[1152], bdet[1152], cdet[1152], ddet[1152], edet[1152];\n    REAL abdet[2304], cddet[2304], cdedet[3456];\n    REAL deter[5760];\n};\n\n__forceinline__ __device__ REAL insphereexact(const Vec3f &pa,\n                                              const Vec3f &pb,\n                                              const Vec3f &pc,\n                                              const Vec3f &pd,\n                                              const Vec3f &pe,\n                                              InSphereExactStorage *s) {\n    int temp8alen, temp8blen, temp16len;\n    int abclen, bcdlen, cdelen, dealen, eablen;\n    int abdlen, bcelen, cdalen, deblen, eaclen;\n    int temp48alen, temp48blen;\n    int abcdlen, bcdelen, cdealen, deablen, eabclen;\n    int xlen, ylen, zlen;\n    int xylen;\n    int alen, blen, clen, dlen, elen;\n    int ablen, cdlen;\n    int deterlen;\n    int i;\n\n    REAL bvirt;\n    REAL avirt, bround, around;\n    REAL c;\n    REAL abig;\n    REAL ahi, alo, bhi, blo;\n    REAL err1, err2, err3;\n    REAL _i, _j;\n    REAL _0;\n\n    Two_Product(pa[0], pb[1], s->axby1, s->axby0);\n    Two_Product(pb[0], pa[1], s->bxay1, s->bxay0);\n    Two_Two_Diff(s->axby1,\n                 s->axby0,\n                 s->bxay1,\n                 s->bxay0,\n                 s->ab[3],\n                 s->ab[2],\n                 s->ab[1],\n                 s->ab[0]);\n\n    Two_Product(pb[0], pc[1], s->bxcy1, s->bxcy0);\n    Two_Product(pc[0], pb[1], s->cxby1, s->cxby0);\n    Two_Two_Diff(s->bxcy1,\n                 s->bxcy0,\n                 s->cxby1,\n                 s->cxby0,\n                 s->bc[3],\n                 s->bc[2],\n                 s->bc[1],\n                 s->bc[0]);\n\n    Two_Product(pc[0], pd[1], s->cxdy1, s->cxdy0);\n    Two_Product(pd[0], pc[1], s->dxcy1, s->dxcy0);\n    Two_Two_Diff(s->cxdy1,\n                 s->cxdy0,\n                 s->dxcy1,\n                 s->dxcy0,\n                 s->cd[3],\n                 s->cd[2],\n                 s->cd[1],\n                 s->cd[0]);\n\n    Two_Product(pd[0], pe[1], s->dxey1, s->dxey0);\n    Two_Product(pe[0], pd[1], s->exdy1, s->exdy0);\n    Two_Two_Diff(s->dxey1,\n                 s->dxey0,\n                 s->exdy1,\n                 s->exdy0,\n                 s->de[3],\n                 s->de[2],\n                 s->de[1],\n                 s->de[0]);\n\n    Two_Product(pe[0], pa[1], s->exay1, s->exay0);\n    Two_Product(pa[0], pe[1], s->axey1, s->axey0);\n    Two_Two_Diff(s->exay1,\n                 s->exay0,\n                 s->axey1,\n                 s->axey0,\n                 s->ea[3],\n                 s->ea[2],\n                 s->ea[1],\n                 s->ea[0]);\n\n    Two_Product(pa[0], pc[1], s->axcy1, s->axcy0);\n    Two_Product(pc[0], pa[1], s->cxay1, s->cxay0);\n    Two_Two_Diff(s->axcy1,\n                 s->axcy0,\n                 s->cxay1,\n                 s->cxay0,\n                 s->ac[3],\n                 s->ac[2],\n                 s->ac[1],\n                 s->ac[0]);\n\n    Two_Product(pb[0], pd[1], s->bxdy1, s->bxdy0);\n    Two_Product(pd[0], pb[1], s->dxby1, s->dxby0);\n    Two_Two_Diff(s->bxdy1,\n                 s->bxdy0,\n                 s->dxby1,\n                 s->dxby0,\n                 s->bd[3],\n                 s->bd[2],\n                 s->bd[1],\n                 s->bd[0]);\n\n    Two_Product(pc[0], pe[1], s->cxey1, s->cxey0);\n    Two_Product(pe[0], pc[1], s->excy1, s->excy0);\n    Two_Two_Diff(s->cxey1,\n                 s->cxey0,\n                 s->excy1,\n                 s->excy0,\n                 s->ce[3],\n                 s->ce[2],\n                 s->ce[1],\n                 s->ce[0]);\n\n    Two_Product(pd[0], pa[1], s->dxay1, s->dxay0);\n    Two_Product(pa[0], pd[1], s->axdy1, s->axdy0);\n    Two_Two_Diff(s->dxay1,\n                 s->dxay0,\n                 s->axdy1,\n                 s->axdy0,\n                 s->da[3],\n                 s->da[2],\n                 s->da[1],\n                 s->da[0]);\n\n    Two_Product(pe[0], pb[1], s->exby1, s->exby0);\n    Two_Product(pb[0], pe[1], s->bxey1, s->bxey0);\n    Two_Two_Diff(s->exby1,\n                 s->exby0,\n                 s->bxey1,\n                 s->bxey0,\n                 s->eb[3],\n                 s->eb[2],\n                 s->eb[1],\n                 s->eb[0]);\n\n    temp8alen = scale_expansion_zeroelim(4, s->bc, pa[2], s->temp8a);\n    temp8blen = scale_expansion_zeroelim(4, s->ac, -pb[2], s->temp8b);\n    temp16len = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp8blen, s->temp8b, s->temp16);\n    temp8alen = scale_expansion_zeroelim(4, s->ab, pc[2], s->temp8a);\n    abclen = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp16len, s->temp16, s->abc);\n\n    temp8alen = scale_expansion_zeroelim(4, s->cd, pb[2], s->temp8a);\n    temp8blen = scale_expansion_zeroelim(4, s->bd, -pc[2], s->temp8b);\n    temp16len = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp8blen, s->temp8b, s->temp16);\n    temp8alen = scale_expansion_zeroelim(4, s->bc, pd[2], s->temp8a);\n    bcdlen = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp16len, s->temp16, s->bcd);\n\n    temp8alen = scale_expansion_zeroelim(4, s->de, pc[2], s->temp8a);\n    temp8blen = scale_expansion_zeroelim(4, s->ce, -pd[2], s->temp8b);\n    temp16len = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp8blen, s->temp8b, s->temp16);\n    temp8alen = scale_expansion_zeroelim(4, s->cd, pe[2], s->temp8a);\n    cdelen = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp16len, s->temp16, s->cde);\n\n    temp8alen = scale_expansion_zeroelim(4, s->ea, pd[2], s->temp8a);\n    temp8blen = scale_expansion_zeroelim(4, s->da, -pe[2], s->temp8b);\n    temp16len = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp8blen, s->temp8b, s->temp16);\n    temp8alen = scale_expansion_zeroelim(4, s->de, pa[2], s->temp8a);\n    dealen = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp16len, s->temp16, s->dea);\n\n    temp8alen = scale_expansion_zeroelim(4, s->ab, pe[2], s->temp8a);\n    temp8blen = scale_expansion_zeroelim(4, s->eb, -pa[2], s->temp8b);\n    temp16len = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp8blen, s->temp8b, s->temp16);\n    temp8alen = scale_expansion_zeroelim(4, s->ea, pb[2], s->temp8a);\n    eablen = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp16len, s->temp16, s->eab);\n\n    temp8alen = scale_expansion_zeroelim(4, s->bd, pa[2], s->temp8a);\n    temp8blen = scale_expansion_zeroelim(4, s->da, pb[2], s->temp8b);\n    temp16len = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp8blen, s->temp8b, s->temp16);\n    temp8alen = scale_expansion_zeroelim(4, s->ab, pd[2], s->temp8a);\n    abdlen = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp16len, s->temp16, s->abd);\n\n    temp8alen = scale_expansion_zeroelim(4, s->ce, pb[2], s->temp8a);\n    temp8blen = scale_expansion_zeroelim(4, s->eb, pc[2], s->temp8b);\n    temp16len = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp8blen, s->temp8b, s->temp16);\n    temp8alen = scale_expansion_zeroelim(4, s->bc, pe[2], s->temp8a);\n    bcelen = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp16len, s->temp16, s->bce);\n\n    temp8alen = scale_expansion_zeroelim(4, s->da, pc[2], s->temp8a);\n    temp8blen = scale_expansion_zeroelim(4, s->ac, pd[2], s->temp8b);\n    temp16len = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp8blen, s->temp8b, s->temp16);\n    temp8alen = scale_expansion_zeroelim(4, s->cd, pa[2], s->temp8a);\n    cdalen = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp16len, s->temp16, s->cda);\n\n    temp8alen = scale_expansion_zeroelim(4, s->eb, pd[2], s->temp8a);\n    temp8blen = scale_expansion_zeroelim(4, s->bd, pe[2], s->temp8b);\n    temp16len = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp8blen, s->temp8b, s->temp16);\n    temp8alen = scale_expansion_zeroelim(4, s->de, pb[2], s->temp8a);\n    deblen = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp16len, s->temp16, s->deb);\n\n    temp8alen = scale_expansion_zeroelim(4, s->ac, pe[2], s->temp8a);\n    temp8blen = scale_expansion_zeroelim(4, s->ce, pa[2], s->temp8b);\n    temp16len = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp8blen, s->temp8b, s->temp16);\n    temp8alen = scale_expansion_zeroelim(4, s->ea, pc[2], s->temp8a);\n    eaclen = fast_expansion_sum_zeroelim(\n        temp8alen, s->temp8a, temp16len, s->temp16, s->eac);\n\n    temp48alen =\n        fast_expansion_sum_zeroelim(cdelen, s->cde, bcelen, s->bce, s->temp48a);\n    temp48blen =\n        fast_expansion_sum_zeroelim(deblen, s->deb, bcdlen, s->bcd, s->temp48b);\n    for (i = 0; i < temp48blen; i++) {\n        s->temp48b[i] = -s->temp48b[i];\n    }\n    bcdelen = fast_expansion_sum_zeroelim(\n        temp48alen, s->temp48a, temp48blen, s->temp48b, s->bcde);\n    xlen = scale_expansion_zeroelim(bcdelen, s->bcde, pa[0], s->temp192);\n    xlen = scale_expansion_zeroelim(xlen, s->temp192, pa[0], s->det384x);\n    ylen = scale_expansion_zeroelim(bcdelen, s->bcde, pa[1], s->temp192);\n    ylen = scale_expansion_zeroelim(ylen, s->temp192, pa[1], s->det384y);\n    zlen = scale_expansion_zeroelim(bcdelen, s->bcde, pa[2], s->temp192);\n    zlen = scale_expansion_zeroelim(zlen, s->temp192, pa[2], s->det384z);\n    xylen = fast_expansion_sum_zeroelim(\n        xlen, s->det384x, ylen, s->det384y, s->detxy);\n    alen =\n        fast_expansion_sum_zeroelim(xylen, s->detxy, zlen, s->det384z, s->adet);\n\n    temp48alen =\n        fast_expansion_sum_zeroelim(dealen, s->dea, cdalen, s->cda, s->temp48a);\n    temp48blen =\n        fast_expansion_sum_zeroelim(eaclen, s->eac, cdelen, s->cde, s->temp48b);\n    for (i = 0; i < temp48blen; i++) {\n        s->temp48b[i] = -s->temp48b[i];\n    }\n    cdealen = fast_expansion_sum_zeroelim(\n        temp48alen, s->temp48a, temp48blen, s->temp48b, s->cdea);\n    xlen = scale_expansion_zeroelim(cdealen, s->cdea, pb[0], s->temp192);\n    xlen = scale_expansion_zeroelim(xlen, s->temp192, pb[0], s->det384x);\n    ylen = scale_expansion_zeroelim(cdealen, s->cdea, pb[1], s->temp192);\n    ylen = scale_expansion_zeroelim(ylen, s->temp192, pb[1], s->det384y);\n    zlen = scale_expansion_zeroelim(cdealen, s->cdea, pb[2], s->temp192);\n    zlen = scale_expansion_zeroelim(zlen, s->temp192, pb[2], s->det384z);\n    xylen = fast_expansion_sum_zeroelim(\n        xlen, s->det384x, ylen, s->det384y, s->detxy);\n    blen =\n        fast_expansion_sum_zeroelim(xylen, s->detxy, zlen, s->det384z, s->bdet);\n\n    temp48alen =\n        fast_expansion_sum_zeroelim(eablen, s->eab, deblen, s->deb, s->temp48a);\n    temp48blen =\n        fast_expansion_sum_zeroelim(abdlen, s->abd, dealen, s->dea, s->temp48b);\n    for (i = 0; i < temp48blen; i++) {\n        s->temp48b[i] = -s->temp48b[i];\n    }\n    deablen = fast_expansion_sum_zeroelim(\n        temp48alen, s->temp48a, temp48blen, s->temp48b, s->deab);\n    xlen = scale_expansion_zeroelim(deablen, s->deab, pc[0], s->temp192);\n    xlen = scale_expansion_zeroelim(xlen, s->temp192, pc[0], s->det384x);\n    ylen = scale_expansion_zeroelim(deablen, s->deab, pc[1], s->temp192);\n    ylen = scale_expansion_zeroelim(ylen, s->temp192, pc[1], s->det384y);\n    zlen = scale_expansion_zeroelim(deablen, s->deab, pc[2], s->temp192);\n    zlen = scale_expansion_zeroelim(zlen, s->temp192, pc[2], s->det384z);\n    xylen = fast_expansion_sum_zeroelim(\n        xlen, s->det384x, ylen, s->det384y, s->detxy);\n    clen =\n        fast_expansion_sum_zeroelim(xylen, s->detxy, zlen, s->det384z, s->cdet);\n\n    temp48alen =\n        fast_expansion_sum_zeroelim(abclen, s->abc, eaclen, s->eac, s->temp48a);\n    temp48blen =\n        fast_expansion_sum_zeroelim(bcelen, s->bce, eablen, s->eab, s->temp48b);\n    for (i = 0; i < temp48blen; i++) {\n        s->temp48b[i] = -s->temp48b[i];\n    }\n    eabclen = fast_expansion_sum_zeroelim(\n        temp48alen, s->temp48a, temp48blen, s->temp48b, s->eabc);\n    xlen = scale_expansion_zeroelim(eabclen, s->eabc, pd[0], s->temp192);\n    xlen = scale_expansion_zeroelim(xlen, s->temp192, pd[0], s->det384x);\n    ylen = scale_expansion_zeroelim(eabclen, s->eabc, pd[1], s->temp192);\n    ylen = scale_expansion_zeroelim(ylen, s->temp192, pd[1], s->det384y);\n    zlen = scale_expansion_zeroelim(eabclen, s->eabc, pd[2], s->temp192);\n    zlen = scale_expansion_zeroelim(zlen, s->temp192, pd[2], s->det384z);\n    xylen = fast_expansion_sum_zeroelim(\n        xlen, s->det384x, ylen, s->det384y, s->detxy);\n    dlen =\n        fast_expansion_sum_zeroelim(xylen, s->detxy, zlen, s->det384z, s->ddet);\n\n    temp48alen =\n        fast_expansion_sum_zeroelim(bcdlen, s->bcd, abdlen, s->abd, s->temp48a);\n    temp48blen =\n        fast_expansion_sum_zeroelim(cdalen, s->cda, abclen, s->abc, s->temp48b);\n    for (i = 0; i < temp48blen; i++) {\n        s->temp48b[i] = -s->temp48b[i];\n    }\n    abcdlen = fast_expansion_sum_zeroelim(\n        temp48alen, s->temp48a, temp48blen, s->temp48b, s->abcd);\n    xlen = scale_expansion_zeroelim(abcdlen, s->abcd, pe[0], s->temp192);\n    xlen = scale_expansion_zeroelim(xlen, s->temp192, pe[0], s->det384x);\n    ylen = scale_expansion_zeroelim(abcdlen, s->abcd, pe[1], s->temp192);\n    ylen = scale_expansion_zeroelim(ylen, s->temp192, pe[1], s->det384y);\n    zlen = scale_expansion_zeroelim(abcdlen, s->abcd, pe[2], s->temp192);\n    zlen = scale_expansion_zeroelim(zlen, s->temp192, pe[2], s->det384z);\n    xylen = fast_expansion_sum_zeroelim(\n        xlen, s->det384x, ylen, s->det384y, s->detxy);\n    elen =\n        fast_expansion_sum_zeroelim(xylen, s->detxy, zlen, s->det384z, s->edet);\n\n    ablen = fast_expansion_sum_zeroelim(alen, s->adet, blen, s->bdet, s->abdet);\n    cdlen = fast_expansion_sum_zeroelim(clen, s->cdet, dlen, s->ddet, s->cddet);\n    cdelen =\n        fast_expansion_sum_zeroelim(cdlen, s->cddet, elen, s->edet, s->cdedet);\n    deterlen = fast_expansion_sum_zeroelim(\n        ablen, s->abdet, cdelen, s->cdedet, s->deter);\n\n    return s->deter[deterlen - 1];\n}\n\n__forceinline__ __device__ REAL insphereadapt(const Vec3f &pa,\n                                              const Vec3f &pb,\n                                              const Vec3f &pc,\n                                              const Vec3f &pd,\n                                              const Vec3f &pe,\n                                              REAL permanent) {\n    REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez;\n    REAL det, errbound;\n\n    REAL aexbey1, bexaey1, bexcey1, cexbey1;\n    REAL cexdey1, dexcey1, dexaey1, aexdey1;\n    REAL aexcey1, cexaey1, bexdey1, dexbey1;\n    REAL aexbey0, bexaey0, bexcey0, cexbey0;\n    REAL cexdey0, dexcey0, dexaey0, aexdey0;\n    REAL aexcey0, cexaey0, bexdey0, dexbey0;\n    REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4];\n    REAL ab3, bc3, cd3, da3, ac3, bd3;\n    REAL abeps, bceps, cdeps, daeps, aceps, bdeps;\n    REAL temp8a[8], temp8b[8], temp8c[8], temp16[16], temp24[24], temp48[48];\n    int temp8alen, temp8blen, temp8clen, temp16len, temp24len, temp48len;\n    REAL xdet[96], ydet[96], zdet[96], xydet[192];\n    int xlen, ylen, zlen, xylen;\n    REAL adet[288], bdet[288], cdet[288], ddet[288];\n    int alen, blen, clen, dlen;\n    REAL abdet[576], cddet[576];\n    int ablen, cdlen;\n    REAL fin1[1152];\n    int finlength;\n\n    REAL aextail, bextail, cextail, dextail;\n    REAL aeytail, beytail, ceytail, deytail;\n    REAL aeztail, beztail, ceztail, deztail;\n\n    REAL bvirt;\n    REAL avirt, bround, around;\n    REAL c;\n    REAL abig;\n    REAL ahi, alo, bhi, blo;\n    REAL err1, err2, err3;\n    REAL _i, _j;\n    REAL _0;\n\n    aex = (REAL)(pa[0] - pe[0]);\n    bex = (REAL)(pb[0] - pe[0]);\n    cex = (REAL)(pc[0] - pe[0]);\n    dex = (REAL)(pd[0] - pe[0]);\n    aey = (REAL)(pa[1] - pe[1]);\n    bey = (REAL)(pb[1] - pe[1]);\n    cey = (REAL)(pc[1] - pe[1]);\n    dey = (REAL)(pd[1] - pe[1]);\n    aez = (REAL)(pa[2] - pe[2]);\n    bez = (REAL)(pb[2] - pe[2]);\n    cez = (REAL)(pc[2] - pe[2]);\n    dez = (REAL)(pd[2] - pe[2]);\n\n    Two_Product(aex, bey, aexbey1, aexbey0);\n    Two_Product(bex, aey, bexaey1, bexaey0);\n    Two_Two_Diff(aexbey1, aexbey0, bexaey1, bexaey0, ab3, ab[2], ab[1], ab[0]);\n    ab[3] = ab3;\n\n    Two_Product(bex, cey, bexcey1, bexcey0);\n    Two_Product(cex, bey, cexbey1, cexbey0);\n    Two_Two_Diff(bexcey1, bexcey0, cexbey1, cexbey0, bc3, bc[2], bc[1], bc[0]);\n    bc[3] = bc3;\n\n    Two_Product(cex, dey, cexdey1, cexdey0);\n    Two_Product(dex, cey, dexcey1, dexcey0);\n    Two_Two_Diff(cexdey1, cexdey0, dexcey1, dexcey0, cd3, cd[2], cd[1], cd[0]);\n    cd[3] = cd3;\n\n    Two_Product(dex, aey, dexaey1, dexaey0);\n    Two_Product(aex, dey, aexdey1, aexdey0);\n    Two_Two_Diff(dexaey1, dexaey0, aexdey1, aexdey0, da3, da[2], da[1], da[0]);\n    da[3] = da3;\n\n    Two_Product(aex, cey, aexcey1, aexcey0);\n    Two_Product(cex, aey, cexaey1, cexaey0);\n    Two_Two_Diff(aexcey1, aexcey0, cexaey1, cexaey0, ac3, ac[2], ac[1], ac[0]);\n    ac[3] = ac3;\n\n    Two_Product(bex, dey, bexdey1, bexdey0);\n    Two_Product(dex, bey, dexbey1, dexbey0);\n    Two_Two_Diff(bexdey1, bexdey0, dexbey1, dexbey0, bd3, bd[2], bd[1], bd[0]);\n    bd[3] = bd3;\n\n    temp8alen = scale_expansion_zeroelim(4, cd, bez, temp8a);\n    temp8blen = scale_expansion_zeroelim(4, bd, -cez, temp8b);\n    temp8clen = scale_expansion_zeroelim(4, bc, dez, temp8c);\n    temp16len = fast_expansion_sum_zeroelim(\n        temp8alen, temp8a, temp8blen, temp8b, temp16);\n    temp24len = fast_expansion_sum_zeroelim(\n        temp8clen, temp8c, temp16len, temp16, temp24);\n    temp48len = scale_expansion_zeroelim(temp24len, temp24, aex, temp48);\n    xlen = scale_expansion_zeroelim(temp48len, temp48, -aex, xdet);\n    temp48len = scale_expansion_zeroelim(temp24len, temp24, aey, temp48);\n    ylen = scale_expansion_zeroelim(temp48len, temp48, -aey, ydet);\n    temp48len = scale_expansion_zeroelim(temp24len, temp24, aez, temp48);\n    zlen = scale_expansion_zeroelim(temp48len, temp48, -aez, zdet);\n    xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);\n    alen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, adet);\n\n    temp8alen = scale_expansion_zeroelim(4, da, cez, temp8a);\n    temp8blen = scale_expansion_zeroelim(4, ac, dez, temp8b);\n    temp8clen = scale_expansion_zeroelim(4, cd, aez, temp8c);\n    temp16len = fast_expansion_sum_zeroelim(\n        temp8alen, temp8a, temp8blen, temp8b, temp16);\n    temp24len = fast_expansion_sum_zeroelim(\n        temp8clen, temp8c, temp16len, temp16, temp24);\n    temp48len = scale_expansion_zeroelim(temp24len, temp24, bex, temp48);\n    xlen = scale_expansion_zeroelim(temp48len, temp48, bex, xdet);\n    temp48len = scale_expansion_zeroelim(temp24len, temp24, bey, temp48);\n    ylen = scale_expansion_zeroelim(temp48len, temp48, bey, ydet);\n    temp48len = scale_expansion_zeroelim(temp24len, temp24, bez, temp48);\n    zlen = scale_expansion_zeroelim(temp48len, temp48, bez, zdet);\n    xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);\n    blen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, bdet);\n\n    temp8alen = scale_expansion_zeroelim(4, ab, dez, temp8a);\n    temp8blen = scale_expansion_zeroelim(4, bd, aez, temp8b);\n    temp8clen = scale_expansion_zeroelim(4, da, bez, temp8c);\n    temp16len = fast_expansion_sum_zeroelim(\n        temp8alen, temp8a, temp8blen, temp8b, temp16);\n    temp24len = fast_expansion_sum_zeroelim(\n        temp8clen, temp8c, temp16len, temp16, temp24);\n    temp48len = scale_expansion_zeroelim(temp24len, temp24, cex, temp48);\n    xlen = scale_expansion_zeroelim(temp48len, temp48, -cex, xdet);\n    temp48len = scale_expansion_zeroelim(temp24len, temp24, cey, temp48);\n    ylen = scale_expansion_zeroelim(temp48len, temp48, -cey, ydet);\n    temp48len = scale_expansion_zeroelim(temp24len, temp24, cez, temp48);\n    zlen = scale_expansion_zeroelim(temp48len, temp48, -cez, zdet);\n    xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);\n    clen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, cdet);\n\n    temp8alen = scale_expansion_zeroelim(4, bc, aez, temp8a);\n    temp8blen = scale_expansion_zeroelim(4, ac, -bez, temp8b);\n    temp8clen = scale_expansion_zeroelim(4, ab, cez, temp8c);\n    temp16len = fast_expansion_sum_zeroelim(\n        temp8alen, temp8a, temp8blen, temp8b, temp16);\n    temp24len = fast_expansion_sum_zeroelim(\n        temp8clen, temp8c, temp16len, temp16, temp24);\n    temp48len = scale_expansion_zeroelim(temp24len, temp24, dex, temp48);\n    xlen = scale_expansion_zeroelim(temp48len, temp48, dex, xdet);\n    temp48len = scale_expansion_zeroelim(temp24len, temp24, dey, temp48);\n    ylen = scale_expansion_zeroelim(temp48len, temp48, dey, ydet);\n    temp48len = scale_expansion_zeroelim(temp24len, temp24, dez, temp48);\n    zlen = scale_expansion_zeroelim(temp48len, temp48, dez, zdet);\n    xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);\n    dlen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, ddet);\n\n    ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);\n    cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet);\n    finlength = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, fin1);\n\n    det = estimate(finlength, fin1);\n    errbound = __fmul_rn(isperrboundB, permanent);\n    if ((det >= errbound) || (-det >= errbound)) {\n        return det;\n    }\n\n    Two_Diff_Tail(pa[0], pe[0], aex, aextail);\n    Two_Diff_Tail(pa[1], pe[1], aey, aeytail);\n    Two_Diff_Tail(pa[2], pe[2], aez, aeztail);\n    Two_Diff_Tail(pb[0], pe[0], bex, bextail);\n    Two_Diff_Tail(pb[1], pe[1], bey, beytail);\n    Two_Diff_Tail(pb[2], pe[2], bez, beztail);\n    Two_Diff_Tail(pc[0], pe[0], cex, cextail);\n    Two_Diff_Tail(pc[1], pe[1], cey, ceytail);\n    Two_Diff_Tail(pc[2], pe[2], cez, ceztail);\n    Two_Diff_Tail(pd[0], pe[0], dex, dextail);\n    Two_Diff_Tail(pd[1], pe[1], dey, deytail);\n    Two_Diff_Tail(pd[2], pe[2], dez, deztail);\n    if ((aextail == 0.0) && (aeytail == 0.0) && (aeztail == 0.0) &&\n        (bextail == 0.0) && (beytail == 0.0) && (beztail == 0.0) &&\n        (cextail == 0.0) && (ceytail == 0.0) && (ceztail == 0.0) &&\n        (dextail == 0.0) && (deytail == 0.0) && (deztail == 0.0)) {\n        return det;\n    }\n\n    errbound = __fmul_rn(isperrboundC, permanent) +\n               __fmul_rn(resulterrbound, Absolute(det));\n    abeps = (__fmul_rn(aex, beytail) + __fmul_rn(bey, aextail)) -\n            (__fmul_rn(aey, bextail) + __fmul_rn(bex, aeytail));\n    bceps = (__fmul_rn(bex, ceytail) + __fmul_rn(cey, bextail)) -\n            (__fmul_rn(bey, cextail) + __fmul_rn(cex, beytail));\n    cdeps = (__fmul_rn(cex, deytail) + __fmul_rn(dey, cextail)) -\n            (__fmul_rn(cey, dextail) + __fmul_rn(dex, ceytail));\n    daeps = (__fmul_rn(dex, aeytail) + __fmul_rn(aey, dextail)) -\n            (__fmul_rn(dey, aextail) + __fmul_rn(aex, deytail));\n    aceps = (__fmul_rn(aex, ceytail) + __fmul_rn(cey, aextail)) -\n            (__fmul_rn(aey, cextail) + __fmul_rn(cex, aeytail));\n    bdeps = (__fmul_rn(bex, deytail) + __fmul_rn(dey, bextail)) -\n            (__fmul_rn(bey, dextail) + __fmul_rn(dex, beytail));\n    det += (((__fmul_rn(bex, bex) + __fmul_rn(bey, bey) + __fmul_rn(bez, bez)) *\n                 ((__fmul_rn(cez, daeps) + __fmul_rn(dez, aceps) +\n                   __fmul_rn(aez, cdeps)) +\n                  (__fmul_rn(ceztail, da3) + __fmul_rn(deztail, ac3) +\n                   __fmul_rn(aeztail, cd3))) +\n             (__fmul_rn(dex, dex) + __fmul_rn(dey, dey) + __fmul_rn(dez, dez)) *\n                 ((__fmul_rn(aez, bceps) - __fmul_rn(bez, aceps) +\n                   __fmul_rn(cez, abeps)) +\n                  (__fmul_rn(aeztail, bc3) - __fmul_rn(beztail, ac3) +\n                   __fmul_rn(ceztail, ab3)))) -\n            ((__fmul_rn(aex, aex) + __fmul_rn(aey, aey) + __fmul_rn(aez, aez)) *\n                 ((__fmul_rn(bez, cdeps) - __fmul_rn(cez, bdeps) +\n                   __fmul_rn(dez, bceps)) +\n                  (__fmul_rn(beztail, cd3) - __fmul_rn(ceztail, bd3) +\n                   __fmul_rn(deztail, bc3))) +\n             (__fmul_rn(cex, cex) + __fmul_rn(cey, cey) + __fmul_rn(cez, cez)) *\n                 ((__fmul_rn(dez, abeps) + __fmul_rn(aez, bdeps) +\n                   __fmul_rn(bez, daeps)) +\n                  (__fmul_rn(deztail, ab3) + __fmul_rn(aeztail, bd3) +\n                   __fmul_rn(beztail, da3))))) +\n           __fmul_rn(2.0,\n                     (((__fmul_rn(bex, bextail) + __fmul_rn(bey, beytail) +\n                        __fmul_rn(bez, beztail)) *\n                           (__fmul_rn(cez, da3) + __fmul_rn(dez, ac3) +\n                            __fmul_rn(aez, cd3)) +\n                       (__fmul_rn(dex, dextail) + __fmul_rn(dey, deytail) +\n                        __fmul_rn(dez, deztail)) *\n                           (__fmul_rn(aez, bc3) - __fmul_rn(bez, ac3) +\n                            __fmul_rn(cez, ab3))) -\n                      ((__fmul_rn(aex, aextail) + __fmul_rn(aey, aeytail) +\n                        __fmul_rn(aez, aeztail)) *\n                           (__fmul_rn(bez, cd3) - __fmul_rn(cez, bd3) +\n                            __fmul_rn(dez, bc3)) +\n                       (__fmul_rn(cex, cextail) + __fmul_rn(cey, ceytail) +\n                        __fmul_rn(cez, ceztail)) *\n                           (__fmul_rn(dez, ab3) + __fmul_rn(aez, bd3) +\n                            __fmul_rn(bez, da3)))));\n    if ((det >= errbound) || (-det >= errbound)) {\n        return det;\n    }\n\n    auto s = (InSphereExactStorage *)malloc(sizeof(InSphereExactStorage));\n    float result = insphereexact(pa, pb, pc, pd, pe, s);\n    free(s);\n    return result;\n}\n\ninline __device__ PredicateResult insphere(const Vec3f &pa,\n                                           const Vec3f &pb,\n                                           const Vec3f &pc,\n                                           const Vec3f &pd,\n                                           const Vec3f &pe) {\n    REAL aex, bex, cex, dex;\n    REAL aey, bey, cey, dey;\n    REAL aez, bez, cez, dez;\n    REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey;\n    REAL aexcey, cexaey, bexdey, dexbey;\n    REAL alift, blift, clift, dlift;\n    REAL ab, bc, cd, da, ac, bd;\n    REAL abc, bcd, cda, dab;\n    REAL aezplus, bezplus, cezplus, dezplus;\n    REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus;\n    REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus;\n    REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus;\n    REAL det;\n    REAL permanent, errbound;\n\n    aex = pa[0] - pe[0];\n    bex = pb[0] - pe[0];\n    cex = pc[0] - pe[0];\n    dex = pd[0] - pe[0];\n    aey = pa[1] - pe[1];\n    bey = pb[1] - pe[1];\n    cey = pc[1] - pe[1];\n    dey = pd[1] - pe[1];\n    aez = pa[2] - pe[2];\n    bez = pb[2] - pe[2];\n    cez = pc[2] - pe[2];\n    dez = pd[2] - pe[2];\n\n    aexbey = __fmul_rn(aex, bey);\n    bexaey = __fmul_rn(bex, aey);\n    ab = aexbey - bexaey;\n    bexcey = __fmul_rn(bex, cey);\n    cexbey = __fmul_rn(cex, bey);\n    bc = bexcey - cexbey;\n    cexdey = __fmul_rn(cex, dey);\n    dexcey = __fmul_rn(dex, cey);\n    cd = cexdey - dexcey;\n    dexaey = __fmul_rn(dex, aey);\n    aexdey = __fmul_rn(aex, dey);\n    da = dexaey - aexdey;\n\n    aexcey = __fmul_rn(aex, cey);\n    cexaey = __fmul_rn(cex, aey);\n    ac = aexcey - cexaey;\n    bexdey = __fmul_rn(bex, dey);\n    dexbey = __fmul_rn(dex, bey);\n    bd = bexdey - dexbey;\n\n    abc = __fmul_rn(aez, bc) - __fmul_rn(bez, ac) + __fmul_rn(cez, ab);\n    bcd = __fmul_rn(bez, cd) - __fmul_rn(cez, bd) + __fmul_rn(dez, bc);\n    cda = __fmul_rn(cez, da) + __fmul_rn(dez, ac) + __fmul_rn(aez, cd);\n    dab = __fmul_rn(dez, ab) + __fmul_rn(aez, bd) + __fmul_rn(bez, da);\n\n    alift = __fmul_rn(aex, aex) + __fmul_rn(aey, aey) + __fmul_rn(aez, aez);\n    blift = __fmul_rn(bex, bex) + __fmul_rn(bey, bey) + __fmul_rn(bez, bez);\n    clift = __fmul_rn(cex, cex) + __fmul_rn(cey, cey) + __fmul_rn(cez, cez);\n    dlift = __fmul_rn(dex, dex) + __fmul_rn(dey, dey) + __fmul_rn(dez, dez);\n\n    det = (__fmul_rn(dlift, abc) - __fmul_rn(clift, dab)) +\n          (__fmul_rn(blift, cda) - __fmul_rn(alift, bcd));\n\n    aezplus = Absolute(aez);\n    bezplus = Absolute(bez);\n    cezplus = Absolute(cez);\n    dezplus = Absolute(dez);\n    aexbeyplus = Absolute(aexbey);\n    bexaeyplus = Absolute(bexaey);\n    bexceyplus = Absolute(bexcey);\n    cexbeyplus = Absolute(cexbey);\n    cexdeyplus = Absolute(cexdey);\n    dexceyplus = Absolute(dexcey);\n    dexaeyplus = Absolute(dexaey);\n    aexdeyplus = Absolute(aexdey);\n    aexceyplus = Absolute(aexcey);\n    cexaeyplus = Absolute(cexaey);\n    bexdeyplus = Absolute(bexdey);\n    dexbeyplus = Absolute(dexbey);\n    permanent = __fmul_rn((__fmul_rn((cexdeyplus + dexceyplus), bezplus) +\n                           __fmul_rn((dexbeyplus + bexdeyplus), cezplus) +\n                           __fmul_rn((bexceyplus + cexbeyplus), dezplus)),\n                          alift) +\n                __fmul_rn((__fmul_rn((dexaeyplus + aexdeyplus), cezplus) +\n                           __fmul_rn((aexceyplus + cexaeyplus), dezplus) +\n                           __fmul_rn((cexdeyplus + dexceyplus), aezplus)),\n                          blift) +\n                __fmul_rn((__fmul_rn((aexbeyplus + bexaeyplus), dezplus) +\n                           __fmul_rn((bexdeyplus + dexbeyplus), aezplus) +\n                           __fmul_rn((dexaeyplus + aexdeyplus), bezplus)),\n                          clift) +\n                __fmul_rn((__fmul_rn((bexceyplus + cexbeyplus), aezplus) +\n                           __fmul_rn((cexaeyplus + aexceyplus), bezplus) +\n                           __fmul_rn((aexbeyplus + bexaeyplus), cezplus)),\n                          dlift);\n    errbound = __fmul_rn(isperrboundA, permanent);\n\n    if (!((det > errbound) || (-det > errbound))) {\n        det = insphereadapt(pa, pb, pc, pd, pe, permanent);\n    }\n\n    if (det > 0) {\n        return PredicateResult::Inside;\n    } else if (det < 0) {\n        return PredicateResult::Outside;\n    } else {\n        return PredicateResult::Ambiguous;\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\n} // namespace radfoam"
  },
  {
    "path": "src/delaunay/sorted_map.cuh",
    "content": "#pragma once\n\n#include \"../utils/cuda_array.h\"\n\nnamespace radfoam {\n\ntemplate <typename K, typename V>\nstruct SortedMap {\n    CUDAArray<K> unique_keys;\n    CUDAArray<V> unique_values;\n    uint32_t num_unique_keys;\n\n    SortedMap() { num_unique_keys = 0; }\n\n    SortedMap(K *keys, V *values, uint32_t num_keys) {\n        insert(keys, values, num_keys);\n    }\n\n    void insert(K *keys, V *values, uint32_t num_keys) {\n\n        if (values != nullptr) {\n            unique_values.resize(num_keys);\n\n            CUB_CALL(cub::DeviceMergeSort::SortPairs(\n                temp_data, temp_bytes, keys, values, num_keys, std::less<K>()));\n        } else {\n            CUB_CALL(cub::DeviceMergeSort::SortKeys(\n                temp_data, temp_bytes, keys, num_keys, std::less<K>()));\n        }\n\n        auto sorted_keys_begin = keys;\n\n        auto is_valid_unique_key =\n            [=] __device__(cub::KeyValuePair<ptrdiff_t, K> pair) {\n                auto i = pair.key;\n                K key = sorted_keys_begin[i];\n                if (!key.is_valid()) {\n                    return false;\n                }\n                if (i > 0) {\n                    K prev_key = sorted_keys_begin[i - 1];\n                    if (key == prev_key) {\n                        return false;\n                    }\n                }\n                return true;\n            };\n\n        auto is_valid_unique_value =\n            [=] __device__(cub::KeyValuePair<ptrdiff_t, V> pair) {\n                auto i = pair.key;\n                K key = sorted_keys_begin[i];\n                if (!key.is_valid()) {\n                    return false;\n                }\n                if (i > 0) {\n                    K prev_key = sorted_keys_begin[i - 1];\n                    if (key == prev_key) {\n                        return false;\n                    }\n                }\n                return true;\n            };\n\n        size_t *num_unique_keys_device;\n        cuda_check(\n            cuMemAlloc(reinterpret_cast<CUdeviceptr *>(&num_unique_keys_device),\n                       sizeof(size_t)));\n\n        unique_keys.resize(num_keys);\n\n        auto enumerated_sorted_keys = enumerate<K>(sorted_keys_begin);\n        auto unenumerated_unique_keys = unenumerate<K>(unique_keys.begin());\n\n        CUB_CALL(cub::DeviceSelect::If(temp_data,\n                                       temp_bytes,\n                                       enumerated_sorted_keys,\n                                       unenumerated_unique_keys,\n                                       num_unique_keys_device,\n                                       num_keys,\n                                       is_valid_unique_key));\n\n        if (values != nullptr) {\n            unique_values.resize(num_keys);\n\n            auto enumerated_sorted_values = enumerate<V>(values);\n            auto unenumerated_unique_values =\n                unenumerate<V>(unique_values.begin());\n\n            CUB_CALL(cub::DeviceSelect::If(temp_data,\n                                           temp_bytes,\n                                           enumerated_sorted_values,\n                                           unenumerated_unique_values,\n                                           num_unique_keys_device,\n                                           num_keys,\n                                           is_valid_unique_value));\n        }\n\n        cuda_check(\n            cuMemcpyDtoH(&num_unique_keys,\n                         reinterpret_cast<CUdeviceptr>(num_unique_keys_device),\n                         sizeof(size_t)));\n        cuda_check(\n            cuMemFree(reinterpret_cast<CUdeviceptr>(num_unique_keys_device)));\n    }\n\n    void clear() {\n        num_unique_keys = 0;\n        unique_keys.clear();\n        unique_values.clear();\n    }\n};\n\n} // namespace radfoam"
  },
  {
    "path": "src/delaunay/triangulation_ops.cu",
    "content": "#include \"triangulation_ops.h\"\n\n#include \"../utils/common_kernels.cuh\"\n#include \"exact_tree_ops.cuh\"\n\nnamespace radfoam {\n\ntemplate <typename coord_scalar>\n__global__ void\nfarthest_neighbor_kernel(const Vec3<coord_scalar> *__restrict__ points,\n                         const uint32_t *point_adjacency,\n                         const uint32_t *point_adjacency_offsets,\n                         uint32_t num_points,\n                         uint32_t *__restrict__ indices,\n                         float *__restrict__ cell_radius) {\n    uint32_t i = (blockIdx.x * blockDim.x + threadIdx.x);\n    if (i >= num_points) {\n        return;\n    }\n\n    Vec3f primal_point = points[i];\n    uint32_t point_adjacency_begin = point_adjacency_offsets[i];\n    uint32_t point_adjacency_end = point_adjacency_offsets[i + 1];\n    uint32_t num_faces = point_adjacency_end - point_adjacency_begin;\n    uint32_t farthest_idx = UINT32_MAX;\n    float sum_distance = 0.0f;\n    float max_distance = 0.0f;\n\n    for (uint32_t i = 0; i < num_faces; ++i) {\n        uint32_t opposite_point_idx =\n            point_adjacency[point_adjacency_begin + i];\n        Vec3f opposite_point = points[opposite_point_idx];\n\n        float distance = (opposite_point - primal_point).norm();\n        sum_distance += 0.5 * distance;\n        if (distance > max_distance) {\n            max_distance = distance;\n            farthest_idx = opposite_point_idx;\n        }\n    }\n\n    indices[i] = farthest_idx;\n    cell_radius[i] = sum_distance / num_faces;\n}\n\ntemplate <typename coord_scalar>\nvoid farthest_neighbor(const Vec3<coord_scalar> *points,\n                       const uint32_t *point_adjacency,\n                       const uint32_t *point_adjacency_offsets,\n                       uint32_t num_points,\n                       uint32_t *indices,\n                       float *cell_radius,\n                       const void *stream) {\n    launch_kernel_1d<1024>(farthest_neighbor_kernel<coord_scalar>,\n                           num_points,\n                           stream,\n                           points,\n                           point_adjacency,\n                           point_adjacency_offsets,\n                           num_points,\n                           indices,\n                           cell_radius);\n}\n\nvoid farthest_neighbor(ScalarType coord_scalar_type,\n                       const void *points,\n                       const void *point_adjacency,\n                       const void *point_adjacency_offsets,\n                       uint32_t num_points,\n                       void *indices,\n                       void *cell_radius,\n                       const void *stream) {\n\n    if (coord_scalar_type == ScalarType::Float32) {\n        farthest_neighbor(\n            static_cast<const Vec3<float> *>(points),\n            static_cast<const uint32_t *>(point_adjacency),\n            static_cast<const uint32_t *>(point_adjacency_offsets),\n            num_points,\n            static_cast<uint32_t *>(indices),\n            static_cast<float *>(cell_radius),\n            stream);\n    } else {\n        throw std::runtime_error(\"unsupported scalar type\");\n    }\n}\n\n} // namespace radfoam"
  },
  {
    "path": "src/delaunay/triangulation_ops.h",
    "content": "#pragma once\n\n#include \"../utils/geometry.h\"\n\nnamespace radfoam {\n\n/// @brief Find the farthest neighbor of each point\nvoid farthest_neighbor(ScalarType coord_scalar_type,\n                       const void *points,\n                       const void *point_adjacency,\n                       const void *point_adjacency_offsets,\n                       uint32_t num_points,\n                       void *indices,\n                       void *cell_radius,\n                       const void *stream = nullptr);\n\n} // namespace radfoam"
  },
  {
    "path": "src/tracing/camera.h",
    "content": "#pragma once\n\n#include \"../utils/geometry.h\"\n\nnamespace radfoam {\n\nstruct Ray {\n    Vec3f origin;\n    Vec3f direction;\n};\n\nenum CameraModel {\n    Pinhole,\n    Fisheye,\n};\n\nstruct Camera {\n    CVec3f position;\n    CVec3f forward;\n    CVec3f right;\n    CVec3f up;\n    float fov;\n    uint32_t width;\n    uint32_t height;\n    CameraModel model;\n\n    RADFOAM_HD void rotate(Vec3f axis, float angle) {\n        auto rotation = Eigen::AngleAxisf(angle, axis);\n        forward = rotation * *forward;\n        right = rotation * *right;\n        up = rotation * *up;\n    }\n};\n\n/// @brief Create a camera pointing from position to target\ninline RADFOAM_HD Camera look_at(const Vec3f &position,\n                                 const Vec3f &target,\n                                 const Vec3f &up,\n                                 float fov,\n                                 uint32_t width,\n                                 uint32_t height,\n                                 CameraModel model = Pinhole) {\n    Camera camera;\n    camera.position = position;\n    camera.forward = (target - position).normalized();\n    camera.right = camera.forward->cross(up).normalized();\n    camera.up = camera.right->cross(*camera.forward).normalized();\n    camera.fov = fov;\n    camera.width = width;\n    camera.height = height;\n    camera.model = model;\n    return camera;\n}\n\n/// @brief Create a ray from the camera through pixel (i, j)\ninline RADFOAM_HD Ray cast_ray(const Camera &camera, int i, int j) {\n    Ray ray;\n    ray.origin = *camera.position;\n    float aspect_ratio = static_cast<float>(camera.width) / camera.height;\n    float x = static_cast<float>(i) / camera.width;\n    float y = static_cast<float>(j) / camera.height;\n\n    float u = (2.0f * x - 1.0f) * aspect_ratio;\n    float v = (1.0f - 2.0f * y);\n    float mask = 1.0f;\n\n    if (camera.model == Pinhole) {\n        float w = 1.0f / tanf(camera.fov * 0.5f);\n        ray.direction =\n            w * *camera.forward + u * *camera.right + v * *camera.up;\n    } else if (camera.model == Fisheye) {\n        float theta = atan2f(v, u);\n        float phi = camera.fov * sqrtf(u * u + v * v);\n        if (phi >= M_PIf) {\n            phi = M_PIf - 1e-6f;\n            mask = 0.0f;\n        }\n        ray.direction = sinf(phi) * cosf(theta) * *camera.right +\n                        sinf(phi) * sinf(theta) * *camera.up +\n                        cosf(phi) * *camera.forward;\n    }\n    ray.direction = ray.direction.normalized() * mask;\n\n    return ray;\n}\n\n} // namespace radfoam\n"
  },
  {
    "path": "src/tracing/pipeline.cu",
    "content": "#include \"../aabb_tree/aabb_tree.h\"\n#include \"../delaunay/triangulation_ops.h\"\n#include \"../utils/cuda_array.h\"\n#include \"../utils/cuda_helpers.h\"\n#include \"../utils/geometry.h\"\n#include \"pipeline.h\"\n\n#include \"../utils/common_kernels.cuh\"\n#include \"sh_utils.cuh\"\n#include \"tracing_utils.cuh\"\n\nnamespace radfoam {\n\ntemplate <typename attr_scalar, int sh_degree, int block_size>\n__global__ void forward(TraceSettings settings,\n                        const Vec3f *__restrict__ points,\n                        const attr_scalar *__restrict__ attributes,\n                        const uint32_t *__restrict__ point_adjacency,\n                        const uint32_t *__restrict__ point_adjacency_offsets,\n                        const Vec4h *__restrict__ adjacent_diff,\n                        const Ray *__restrict__ rays,\n                        uint32_t num_rays,\n                        const uint32_t *__restrict__ start_point_index,\n                        uint32_t num_depth_quantiles,\n                        const float *__restrict__ depth_quantiles,\n                        attr_scalar *__restrict__ ray_rgba,\n                        float *__restrict__ quantile_depths,\n                        uint32_t *__restrict__ quantile_point_indices,\n                        uint32_t *__restrict__ num_intersections,\n                        attr_scalar *__restrict__ point_contribution) {\n\n    uint32_t thread_idx = blockIdx.x * blockDim.x + threadIdx.x;\n    if (thread_idx >= num_rays)\n        return;\n\n    constexpr int sh_dim = 3 * (1 + sh_degree) * (1 + sh_degree);\n    constexpr int attr_memory_size = 1 + sh_dim;\n\n    Ray ray = rays[thread_idx];\n    ray.direction /= ray.direction.norm();\n\n    const float *ray_depth_quantiles =\n        depth_quantiles + thread_idx * num_depth_quantiles;\n\n    auto sh_coeffs = sh_coefficients<sh_degree>(ray.direction);\n\n    auto load_attributes = [&](uint32_t v_idx, Vec3f &rgb, float &s) {\n        const attr_scalar *attr_ptr = attributes + v_idx * attr_memory_size;\n        s = (float)attr_ptr[attr_memory_size - 1];\n        if (s > 1e-6f) {\n            rgb = load_sh_as_rgb<attr_scalar, sh_degree>(sh_coeffs, attr_ptr);\n        } else {\n            rgb = Vec3f::Zero();\n        }\n    };\n\n    float transmittance = 1.0f;\n    Vec3f accumulated_rgb = Vec3f::Zero();\n\n    uint32_t current_quantile_idx = 0;\n    float current_quantile;\n    if (depth_quantiles) {\n        current_quantile = ray_depth_quantiles[current_quantile_idx];\n    }\n\n    auto functor = [&](uint32_t point_idx,\n                       float t_0,\n                       float t_1,\n                       const Vec3f &current_point,\n                       const Vec3f &next_point) {\n        Vec3f rgb_primal;\n        float s_primal;\n\n        load_attributes(point_idx, rgb_primal, s_primal);\n\n        float delta_t = fmaxf(t_1 - t_0, 0.0f);\n        float alpha = 1 - expf(-s_primal * delta_t);\n        float weight = transmittance * alpha;\n\n        if (point_contribution) {\n            atomicAdd(point_contribution + point_idx, (attr_scalar)weight);\n        }\n        accumulated_rgb += weight * rgb_primal;\n\n        float next_transmittance = transmittance * (1 - alpha);\n        while (current_quantile_idx < num_depth_quantiles &&\n               next_transmittance < current_quantile) {\n            quantile_depths[thread_idx * num_depth_quantiles +\n                            current_quantile_idx] =\n                t_0 + logf(transmittance / current_quantile) / s_primal;\n            quantile_point_indices[thread_idx * num_depth_quantiles +\n                                   current_quantile_idx] = point_idx;\n            current_quantile_idx++;\n            if (current_quantile_idx < num_depth_quantiles) {\n                current_quantile = ray_depth_quantiles[current_quantile_idx];\n            }\n        }\n\n        transmittance = next_transmittance;\n\n        return transmittance > settings.weight_threshold;\n    };\n\n    uint32_t start_point = start_point_index[thread_idx];\n\n    uint32_t n = trace<block_size, 4>(ray,\n                                      points,\n                                      point_adjacency,\n                                      point_adjacency_offsets,\n                                      adjacent_diff,\n                                      start_point,\n                                      settings.max_intersections,\n                                      functor);\n\n    while (current_quantile_idx < num_depth_quantiles) {\n        quantile_depths[thread_idx * num_depth_quantiles +\n                        current_quantile_idx] = -1.0f;\n        quantile_point_indices[thread_idx * num_depth_quantiles +\n                               current_quantile_idx] = UINT32_MAX;\n        current_quantile_idx++;\n    }\n\n    for (uint32_t i = 0; i < 3; ++i) {\n        ray_rgba[thread_idx * 4 + i] = attr_scalar(accumulated_rgb[i]);\n    }\n    ray_rgba[thread_idx * 4 + 3] = attr_scalar(1 - transmittance);\n\n    if (num_intersections)\n        num_intersections[thread_idx] = n;\n}\n\ntemplate <typename attr_scalar, int sh_degree, int block_size>\n__global__ void backward(TraceSettings settings,\n                         const Vec3f *__restrict__ points,\n                         const attr_scalar *__restrict__ attributes,\n                         const uint32_t *__restrict__ point_adjacency,\n                         const uint32_t *__restrict__ point_adjacency_offsets,\n                         const Vec4h *__restrict__ adjacent_diff,\n                         const Ray *__restrict__ rays,\n                         uint32_t num_rays,\n                         const uint32_t *__restrict__ start_point_index,\n                         uint32_t num_depth_quantiles,\n                         const float *__restrict__ depth_quantiles,\n                         const uint32_t *__restrict__ quantile_point_indices,\n                         const attr_scalar *__restrict__ ray_rgba,\n                         const attr_scalar *__restrict__ ray_rgba_grad,\n                         const float *__restrict__ depth_grad,\n                         const attr_scalar *__restrict__ ray_error,\n                         Ray *__restrict__ ray_grad,\n                         Vec3f *__restrict__ points_grad,\n                         attr_scalar *__restrict__ attribute_grad,\n                         attr_scalar *__restrict__ point_error) {\n\n    uint32_t thread_idx = blockIdx.x * blockDim.x + threadIdx.x;\n    if (thread_idx >= num_rays)\n        return;\n\n    constexpr int sh_dim = 3 * (1 + sh_degree) * (1 + sh_degree);\n    constexpr int attr_memory_size = 1 + sh_dim;\n\n    Ray ray = rays[thread_idx];\n    ray.direction /= ray.direction.norm();\n\n    const float *ray_depth_grad = depth_grad + thread_idx * num_depth_quantiles;\n    const float *ray_depth_quantiles =\n        depth_quantiles + thread_idx * num_depth_quantiles;\n\n    auto sh_coeffs = sh_coefficients<sh_degree>(ray.direction);\n\n    auto load_attributes = [&](uint32_t v_idx, Vec3f &rgb, float &s) {\n        const attr_scalar *attr_ptr = attributes + v_idx * attr_memory_size;\n        s = (float)attr_ptr[attr_memory_size - 1];\n        if (s > 1e-6f) {\n            rgb = load_sh_as_rgb<attr_scalar, sh_degree>(sh_coeffs, attr_ptr);\n        } else {\n            rgb = Vec3f::Zero();\n        }\n    };\n\n    Vec4f rgba_grad, rgba;\n#pragma unroll\n    for (uint32_t i = 0; i < 4; ++i) {\n        rgba_grad[i] = (float)ray_rgba_grad[thread_idx * 4 + i];\n        rgba[i] = (float)ray_rgba[thread_idx * 4 + i];\n    }\n\n    float error;\n    if (ray_error) {\n        error = (float)ray_error[thread_idx];\n    }\n\n    uint32_t current_quantile_idx = 0;\n    float current_quantile;\n    if (depth_quantiles) {\n        current_quantile = ray_depth_quantiles[current_quantile_idx];\n    }\n    float current_depth_grad = 0.0f;\n    for (uint32_t i = 0; i < num_depth_quantiles; ++i) {\n        if (quantile_point_indices[thread_idx * num_depth_quantiles + i] !=\n            UINT32_MAX) {\n            uint32_t point_idx =\n                quantile_point_indices[thread_idx * num_depth_quantiles + i];\n            float s = (float)\n                attributes[point_idx * attr_memory_size + attr_memory_size - 1];\n            current_depth_grad += ray_depth_grad[i] / s;\n        }\n    }\n\n    float transmittance = 1.0f;\n    Vec3f accumulated_rgb = Vec3f::Zero();\n\n    uint32_t prev_point_idx = UINT32_MAX;\n    Vec3f prev_point = Vec3f::Zero();\n    Vec3f prev_point_grad = Vec3f::Zero();\n\n    Vec3f current_point_grad = Vec3f::Zero();\n    Vec3f next_point_grad = Vec3f::Zero();\n\n    auto functor = [&](uint32_t point_idx,\n                       float t_0,\n                       float t_1,\n                       const Vec3f &current_point,\n                       const Vec3f &next_point) {\n        Vec3f rgb_primal;\n        float s_primal;\n\n        load_attributes(point_idx, rgb_primal, s_primal);\n\n        float delta_t = fmaxf(t_1 - t_0, 0.0f);\n        float alpha = 1 - expf(-s_primal * delta_t);\n        float weight = transmittance * alpha;\n        float dalpha_ds_primal = delta_t * (1 - alpha);\n        float dalpha_ddelta_t = 0.0f;\n        if (delta_t > 0.0f) {\n            dalpha_ddelta_t = s_primal * (1 - alpha);\n        }\n\n        accumulated_rgb += weight * rgb_primal;\n        if (point_error) {\n            atomicAdd(point_error + point_idx, (attr_scalar)(weight * error));\n        }\n\n        Vec3f dL_drgb_primal = rgba_grad.template head<3>() * weight;\n\n        Vec3f rgb_rest = rgba.template head<3>() - accumulated_rgb;\n        rgb_rest /= (transmittance * (1 - alpha + 1e-6f));\n\n        float dL_dalpha =\n            transmittance *\n            (rgb_primal - rgb_rest).dot(rgba_grad.template head<3>());\n        dL_dalpha += (1 - rgba[3]) * rgba_grad[3] / (1 - alpha + 1e-6f);\n\n        float dL_ds_primal = dL_dalpha * dalpha_ds_primal;\n        float dL_ddelta_t = dL_dalpha * dalpha_ddelta_t;\n\n        float dL_dt0 = 0.0f;\n\n        float next_transmittance = transmittance * (1 - alpha);\n        while (current_quantile_idx < num_depth_quantiles &&\n               next_transmittance < current_quantile) {\n\n            float depth_grad_i =\n                ray_depth_grad[current_quantile_idx] / s_primal;\n            dL_dt0 += depth_grad_i;\n            dL_ds_primal += -depth_grad_i *\n                            logf(transmittance / current_quantile) / s_primal;\n\n            current_depth_grad -= depth_grad_i;\n\n            current_quantile_idx++;\n            if (current_quantile_idx < num_depth_quantiles) {\n                current_quantile = ray_depth_quantiles[current_quantile_idx];\n            }\n        }\n\n        if (current_quantile_idx < num_depth_quantiles) {\n            dL_ds_primal += -delta_t * current_depth_grad;\n            dL_ddelta_t += -s_primal * current_depth_grad;\n        }\n\n        dL_dt0 += -dL_ddelta_t;\n        float dL_dt1 = dL_ddelta_t;\n\n        Vec3f dt0_dprev_point;\n        if (prev_point_idx != UINT32_MAX) {\n            dt0_dprev_point =\n                cell_intersection_grad(prev_point, current_point, ray);\n        } else {\n            dt0_dprev_point = Vec3f::Zero();\n        }\n\n        Vec3f dt1_dcurrent_point =\n            cell_intersection_grad(current_point, next_point, ray);\n        Vec3f dt0_dcurrent_point =\n            cell_intersection_grad(current_point, prev_point, ray);\n\n        Vec3f dt1_dnext_point =\n            cell_intersection_grad(next_point, current_point, ray);\n\n        prev_point_grad += dL_dt0 * dt0_dprev_point;\n        current_point_grad +=\n            dL_dt0 * dt0_dcurrent_point + dL_dt1 * dt1_dcurrent_point;\n        next_point_grad += dL_dt1 * dt1_dnext_point;\n\n        if (prev_point_idx != UINT32_MAX) {\n            atomic_add_vec(points_grad + prev_point_idx, prev_point_grad);\n        }\n        prev_point = current_point;\n        prev_point_idx = point_idx;\n        prev_point_grad = current_point_grad;\n\n        current_point_grad = next_point_grad;\n        next_point_grad = Vec3f::Zero();\n\n        transmittance = next_transmittance;\n\n        for (uint32_t i = 0; i < 3; ++i) {\n            if (rgb_primal[i] == 0.0f) {\n                dL_drgb_primal[i] = 0.0f;\n            }\n        }\n        write_rgb_grad_to_sh<attr_scalar, sh_degree>(\n            sh_coeffs,\n            dL_drgb_primal,\n            attribute_grad + point_idx * attr_memory_size);\n        atomicAdd(attribute_grad + point_idx * attr_memory_size +\n                      (attr_memory_size - 1),\n                  (attr_scalar)dL_ds_primal);\n\n        return transmittance > settings.weight_threshold;\n    };\n\n    uint32_t start_point = start_point_index[thread_idx];\n\n    trace<block_size, 2>(ray,\n                         points,\n                         point_adjacency,\n                         point_adjacency_offsets,\n                         adjacent_diff,\n                         start_point,\n                         settings.max_intersections,\n                         functor);\n}\n\ntemplate <typename attr_scalar, int sh_degree, int block_size>\n__global__ void\nvisualization(TraceSettings settings,\n              const Vec3f *__restrict__ points,\n              const attr_scalar *__restrict__ attributes,\n              const uint32_t *__restrict__ point_adjacency,\n              const uint32_t *__restrict__ point_adjacency_offsets,\n              const Vec4h *__restrict__ adjacent_diff,\n              VisualizationSettings vis_settings,\n              CMapTable cmap_table,\n              Camera camera,\n              cudaSurfaceObject_t output_rgba,\n              uint32_t start_point_index) {\n\n    uint32_t thread_idx = blockIdx.x * blockDim.x + threadIdx.x;\n    uint32_t pix_i = thread_idx % camera.width;\n    uint32_t pix_j = thread_idx / camera.width;\n\n    if (pix_i >= camera.width || pix_j >= camera.height)\n        return;\n\n    constexpr int sh_dim = 3 * (1 + sh_degree) * (1 + sh_degree);\n    constexpr int attr_memory_size = 1 + sh_dim;\n\n    Ray ray = cast_ray(camera, pix_i, pix_j);\n    if (ray.direction.norm() < 0.1f) {\n        surf2Dwrite(0, output_rgba, 4 * pix_i, camera.height - 1 - pix_j);\n        return;\n    }\n\n    auto sh_coeffs = sh_coefficients<sh_degree>(ray.direction);\n\n    auto load_attributes = [&](uint32_t v_idx, Vec3f &rgb, float &s) {\n        const attr_scalar *attr_ptr = attributes + v_idx * attr_memory_size;\n        s = (float)attr_ptr[attr_memory_size - 1];\n        if (s > 1e-6f) {\n            rgb = load_sh_as_rgb<attr_scalar, sh_degree>(sh_coeffs, attr_ptr);\n        } else {\n            rgb = Vec3f::Zero();\n        }\n    };\n\n    float transmittance = 1.0f;\n    Vec3f accumulated_rgb = Vec3f::Zero();\n    float depth = 0.0f;\n    bool depth_quantile_passed = false;\n\n    auto functor = [&](uint32_t point_idx,\n                       float t_0,\n                       float t_1,\n                       const Vec3f &current_point,\n                       const Vec3f &next_point) {\n        Vec3f rgb_primal;\n        float s_primal;\n\n        load_attributes(point_idx, rgb_primal, s_primal);\n\n        float delta_t = fmaxf(t_1 - t_0, 0.0f);\n        float alpha = 1 - expf(-s_primal * delta_t);\n\n        accumulated_rgb += transmittance * alpha * rgb_primal;\n\n        float next_transmittance = transmittance * (1 - alpha);\n        if (!depth_quantile_passed &&\n            next_transmittance < vis_settings.depth_quantile) {\n            depth = t_0 + logf(transmittance / vis_settings.depth_quantile) /\n                              s_primal;\n            depth_quantile_passed = true;\n        }\n\n        transmittance = next_transmittance;\n\n        return transmittance > settings.weight_threshold;\n    };\n\n    uint32_t n = trace<block_size, 4>(ray,\n                                      points,\n                                      point_adjacency,\n                                      point_adjacency_offsets,\n                                      adjacent_diff,\n                                      start_point_index,\n                                      settings.max_intersections,\n                                      functor);\n\n    uint32_t out;\n\n    if (vis_settings.mode == VisualizationMode::RGB) {\n        Vec3f color = accumulated_rgb;\n\n        Vec3f bg_color;\n        if (vis_settings.checker_bg) {\n            int is = 2 * ((pix_i / 20) % 2) - 1;\n            int js = 2 * ((pix_j / 20) % 2) - 1;\n            if (is * js > 0) {\n                bg_color = Vec3f(0.3f, 0.3f, 0.3f);\n            } else {\n                bg_color = Vec3f(0.5f, 0.5f, 0.5f);\n            }\n        } else {\n            bg_color = *vis_settings.bg_color;\n        }\n\n        color += transmittance * bg_color;\n\n        out = make_rgba8(color[0], color[1], color[2], 1.0f);\n    } else if (vis_settings.mode == VisualizationMode::Depth) {\n        float val = depth / vis_settings.max_depth;\n\n        Vec3f color = colormap(val, vis_settings.color_map, cmap_table);\n\n        out = make_rgba8(color[0], color[1], color[2], 1.0f);\n    } else if (vis_settings.mode == VisualizationMode::Alpha) {\n        out = make_rgba8(1.0f - transmittance,\n                         1.0f - transmittance,\n                         1.0f - transmittance,\n                         1.0f);\n    } else if (vis_settings.mode == VisualizationMode::Intersections) {\n        float val = float(n - 1) / float(settings.max_intersections);\n\n        Vec3f color = colormap(val, vis_settings.color_map, cmap_table);\n\n        out = make_rgba8(color[0], color[1], color[2], 1.0f);\n    }\n\n    surf2Dwrite(out, output_rgba, 4 * pix_i, camera.height - 1 - pix_j);\n}\n\ntemplate <typename attr_scalar, int sh_degree, int block_size>\n__global__ void benchmark(TraceSettings settings,\n                          const Vec3f *__restrict__ points,\n                          const attr_scalar *__restrict__ attributes,\n                          const uint32_t *__restrict__ point_adjacency,\n                          const uint32_t *__restrict__ point_adjacency_offsets,\n                          const Vec4h *__restrict__ adjacent_diff,\n                          Camera camera,\n                          const uint32_t *__restrict__ start_point_index,\n                          uint32_t *__restrict__ output_rgba) {\n\n    uint32_t thread_idx = blockIdx.x * blockDim.x + threadIdx.x;\n    uint32_t pix_i = thread_idx % camera.width;\n    uint32_t pix_j = thread_idx / camera.width;\n\n    if (pix_i >= camera.width || pix_j >= camera.height)\n        return;\n\n    constexpr int sh_dim = 3 * (1 + sh_degree) * (1 + sh_degree);\n    constexpr int attr_memory_size = 1 + sh_dim;\n\n    Ray ray = cast_ray(camera, pix_i, pix_j);\n    if (ray.direction.norm() < 0.1f) {\n        output_rgba[thread_idx] = 0;\n        return;\n    }\n\n    auto sh_coeffs = sh_coefficients<sh_degree>(ray.direction);\n\n    auto load_attributes = [&](uint32_t v_idx, Vec3f &rgb, float &s) {\n        const attr_scalar *attr_ptr = attributes + v_idx * attr_memory_size;\n        s = (float)attr_ptr[attr_memory_size - 1];\n        if (s > 1e-6f) {\n            rgb = load_sh_as_rgb<attr_scalar, sh_degree>(sh_coeffs, attr_ptr);\n        } else {\n            rgb = Vec3f::Zero();\n        }\n    };\n\n    float transmittance = 1.0f;\n    Vec3f accumulated_rgb = Vec3f::Zero();\n\n    auto functor = [&](uint32_t point_idx,\n                       float t_0,\n                       float t_1,\n                       const Vec3f &current_point,\n                       const Vec3f &next_point) {\n        Vec3f rgb_primal;\n        float s_primal;\n\n        load_attributes(point_idx, rgb_primal, s_primal);\n\n        float delta_t = fmaxf(t_1 - t_0, 0.0f);\n        float alpha = 1 - expf(-s_primal * delta_t);\n\n        accumulated_rgb += transmittance * alpha * rgb_primal;\n        transmittance = transmittance * (1 - alpha);\n\n        return transmittance > settings.weight_threshold;\n    };\n\n    uint32_t n = trace<block_size, 4>(ray,\n                                      points,\n                                      point_adjacency,\n                                      point_adjacency_offsets,\n                                      adjacent_diff,\n                                      *start_point_index,\n                                      settings.max_intersections,\n                                      functor);\n\n    output_rgba[thread_idx] = make_rgba8(\n        accumulated_rgb[0], accumulated_rgb[1], accumulated_rgb[2], 1.0f);\n}\n\n__global__ void prefetch_adjacent_diff_kernel(\n    const Vec3f *__restrict__ points,\n    uint32_t num_points,\n    uint32_t point_adjacency_size,\n    const uint32_t *__restrict__ point_adjacency,\n    const uint32_t *__restrict__ point_adjacency_offsets,\n    Vec4h *__restrict__ adjacent_diff) {\n    uint32_t i = blockIdx.x * blockDim.x + threadIdx.x;\n    if (i >= num_points)\n        return;\n\n    Vec3f p = points[i];\n    uint32_t offset_start = point_adjacency_offsets[i];\n    uint32_t offset_end = point_adjacency_offsets[i + 1];\n    uint32_t num_adjacent = offset_end - offset_start;\n\n    for (uint32_t j = 0; j < num_adjacent; ++j) {\n        uint32_t adjacent_idx = point_adjacency[offset_start + j];\n        Vec3f q = points[adjacent_idx];\n        Vec3f diff = q - p;\n        adjacent_diff[offset_start + j] = Vec4h(diff[0], diff[1], diff[2], 0);\n    }\n}\n\nvoid prefetch_adjacent_diff(const Vec3f *points,\n                            uint32_t num_points,\n                            uint32_t point_adjacency_size,\n                            const uint32_t *point_adjacency,\n                            const uint32_t *point_adjacency_offsets,\n                            Vec4h *adjacent_diff,\n                            const void *stream) {\n    launch_kernel_1d<256>(prefetch_adjacent_diff_kernel,\n                          num_points,\n                          stream,\n                          points,\n                          num_points,\n                          point_adjacency_size,\n                          point_adjacency,\n                          point_adjacency_offsets,\n                          adjacent_diff);\n}\n\ntemplate <typename attr_scalar, int sh_degree>\nclass CUDATracingPipeline : public Pipeline {\n  public:\n    CUDATracingPipeline() = default;\n\n    virtual ~CUDATracingPipeline() {}\n\n    void trace_forward(const TraceSettings &settings,\n                       uint32_t num_points,\n                       const Vec3f *points,\n                       const void *attributes,\n                       uint32_t point_adjacency_size,\n                       const uint32_t *point_adjacency,\n                       const uint32_t *point_adjacency_offsets,\n                       uint32_t num_rays,\n                       const Ray *rays,\n                       const uint32_t *start_point_index,\n                       uint32_t num_depth_quantiles,\n                       const float *depth_quantiles,\n                       void *ray_rgba,\n                       float *quantile_dpeths,\n                       uint32_t *quantile_point_indices,\n                       uint32_t *num_intersections,\n                       void *point_contribution) override {\n\n        CUDAArray<Vec4h> adjacent_diff(point_adjacency_size + 32);\n        prefetch_adjacent_diff(reinterpret_cast<const Vec3f *>(points),\n                               num_points,\n                               point_adjacency_size,\n                               point_adjacency,\n                               point_adjacency_offsets,\n                               adjacent_diff.begin(),\n                               nullptr);\n\n        constexpr uint32_t block_size = 128;\n        launch_kernel_1d<block_size>(\n            forward<attr_scalar, sh_degree, block_size>,\n            num_rays,\n            nullptr,\n            settings,\n            points,\n            reinterpret_cast<const attr_scalar *>(attributes),\n            point_adjacency,\n            point_adjacency_offsets,\n            adjacent_diff.begin(),\n            rays,\n            num_rays,\n            start_point_index,\n            num_depth_quantiles,\n            depth_quantiles,\n            static_cast<attr_scalar *>(ray_rgba),\n            quantile_dpeths,\n            quantile_point_indices,\n            num_intersections,\n            static_cast<attr_scalar *>(point_contribution));\n    }\n\n    void trace_backward(const TraceSettings &settings,\n                        uint32_t num_points,\n                        const Vec3f *points,\n                        const void *attributes,\n                        uint32_t point_adjacency_size,\n                        const uint32_t *point_adjacency,\n                        const uint32_t *point_adjacency_offsets,\n                        uint32_t num_rays,\n                        const Ray *rays,\n                        const uint32_t *start_point_index,\n                        uint32_t num_depth_quantiles,\n                        const float *depth_quantiles,\n                        const uint32_t *quantile_point_indices,\n                        const void *ray_rgba,\n                        const void *ray_rgba_grad,\n                        const float *depth_grad,\n                        const void *ray_error,\n                        Ray *ray_grad,\n                        Vec3f *points_grad,\n                        void *attribute_grad,\n                        void *point_error) override {\n\n        CUDAArray<Vec4h> adjacent_diff(point_adjacency_size + 32);\n        prefetch_adjacent_diff(reinterpret_cast<const Vec3f *>(points),\n                               num_points,\n                               point_adjacency_size,\n                               point_adjacency,\n                               point_adjacency_offsets,\n                               adjacent_diff.begin(),\n                               nullptr);\n\n        constexpr uint32_t block_size = 128;\n        launch_kernel_1d<block_size>(\n            backward<attr_scalar, sh_degree, block_size>,\n            num_rays,\n            nullptr,\n            settings,\n            points,\n            reinterpret_cast<const attr_scalar *>(attributes),\n            point_adjacency,\n            point_adjacency_offsets,\n            adjacent_diff.begin(),\n            rays,\n            num_rays,\n            start_point_index,\n            num_depth_quantiles,\n            depth_quantiles,\n            quantile_point_indices,\n            static_cast<const attr_scalar *>(ray_rgba),\n            static_cast<const attr_scalar *>(ray_rgba_grad),\n            depth_grad,\n            static_cast<const attr_scalar *>(ray_error),\n            ray_grad,\n            points_grad,\n            static_cast<attr_scalar *>(attribute_grad),\n            static_cast<attr_scalar *>(point_error));\n    }\n\n    void trace_visualization(const TraceSettings &settings,\n                             const VisualizationSettings &vis_settings,\n                             const Camera &camera,\n                             CMapTable cmap_table,\n                             uint32_t num_points,\n                             uint32_t num_tets,\n                             const void *points,\n                             const void *attributes,\n                             const void *point_adjacency,\n                             const void *point_adjacency_offsets,\n                             const void *adjacent_diff,\n                             uint32_t start_index,\n                             uint64_t output_surface,\n                             const void *stream) override {\n\n        uint32_t num_rays = camera.width * camera.height;\n        constexpr uint32_t block_size = 128;\n\n        launch_kernel_1d<block_size>(\n            visualization<attr_scalar, sh_degree, block_size>,\n            num_rays,\n            stream,\n            settings,\n            reinterpret_cast<const Vec3f *>(points),\n            reinterpret_cast<const attr_scalar *>(attributes),\n            reinterpret_cast<const uint32_t *>(point_adjacency),\n            reinterpret_cast<const uint32_t *>(point_adjacency_offsets),\n            reinterpret_cast<const Vec4h *>(adjacent_diff),\n            vis_settings,\n            cmap_table,\n            camera,\n            output_surface,\n            start_index);\n    }\n\n    void trace_benchmark(const TraceSettings &settings,\n                         uint32_t num_points,\n                         const Vec3f *points,\n                         const void *attributes,\n                         const uint32_t *point_adjacency,\n                         const uint32_t *point_adjacency_offsets,\n                         const Vec4h *adjacent_diff,\n                         Camera camera,\n                         const uint32_t *start_point_index,\n                         uint32_t *ray_rgba) override {\n\n        uint32_t num_rays = camera.width * camera.height;\n\n        constexpr uint32_t block_size = 512;\n        launch_kernel_1d<block_size>(\n            benchmark<attr_scalar, sh_degree, block_size>,\n            num_rays,\n            nullptr,\n            settings,\n            points,\n            reinterpret_cast<const attr_scalar *>(attributes),\n            point_adjacency,\n            point_adjacency_offsets,\n            adjacent_diff,\n            camera,\n            start_point_index,\n            ray_rgba);\n    }\n\n    uint32_t attribute_dim() const override {\n        return 1 + 3 * (1 + sh_degree) * (1 + sh_degree);\n    }\n\n    ScalarType attribute_type() const override {\n        return scalar_code<attr_scalar>();\n    }\n};\n\nstd::shared_ptr<Pipeline> create_pipeline(int sh_degree, ScalarType attr_type) {\n\n    if (attr_type == ScalarType::Float32) {\n        if (sh_degree == 0) {\n            return std::make_shared<CUDATracingPipeline<float, 0>>();\n        } else if (sh_degree == 1) {\n            return std::make_shared<CUDATracingPipeline<float, 1>>();\n        } else if (sh_degree == 2) {\n            return std::make_shared<CUDATracingPipeline<float, 2>>();\n        } else if (sh_degree == 3) {\n            return std::make_shared<CUDATracingPipeline<float, 3>>();\n        } else {\n            throw std::runtime_error(\"Unsupported SH degree\");\n        }\n    } else if (attr_type == ScalarType::Float16) {\n        if (sh_degree == 0) {\n            return std::make_shared<CUDATracingPipeline<__half, 0>>();\n        } else if (sh_degree == 1) {\n            return std::make_shared<CUDATracingPipeline<__half, 1>>();\n        } else if (sh_degree == 2) {\n            return std::make_shared<CUDATracingPipeline<__half, 2>>();\n        } else if (sh_degree == 3) {\n            return std::make_shared<CUDATracingPipeline<__half, 3>>();\n        } else {\n            throw std::runtime_error(\"Unsupported SH degree\");\n        }\n    } else {\n        throw std::runtime_error(\"Unsupported attribute type\");\n    }\n}\n\n} // namespace radfoam"
  },
  {
    "path": "src/tracing/pipeline.h",
    "content": "#pragma once\n\n#include <memory>\n\n#include \"../utils/typing.h\"\n#include \"camera.h\"\n\nnamespace radfoam {\n\nstruct TraceSettings {\n    float weight_threshold;\n    uint32_t max_intersections;\n};\n\ninline TraceSettings default_trace_settings() {\n    TraceSettings settings;\n    settings.weight_threshold = 0.001f;\n    settings.max_intersections = 1024;\n    return settings;\n}\n\nenum VisualizationMode {\n    RGB = 0,\n    Depth = 1,\n    Alpha = 2,\n    Intersections = 3,\n};\n\nstruct VisualizationSettings {\n    VisualizationMode mode;\n    ColorMap color_map;\n    CVec3f bg_color;\n    bool checker_bg;\n    float max_depth;\n    float depth_quantile;\n};\n\ninline VisualizationSettings default_visualization_settings() {\n    VisualizationSettings settings;\n    settings.mode = RGB;\n    settings.color_map = Turbo;\n    settings.bg_color = Vec3f(1.0f, 1.0f, 1.0f);\n    settings.checker_bg = false;\n    settings.max_depth = 10.0f;\n    settings.depth_quantile = 0.5f;\n    return settings;\n}\n\n/// @brief Prefetch offset for each edge in the adjacency matrix\nvoid prefetch_adjacent_diff(const Vec3f *points,\n                            uint32_t num_points,\n                            uint32_t point_adjacency_size,\n                            const uint32_t *point_adjacency,\n                            const uint32_t *point_adjacency_offsets,\n                            Vec4h *adjacent_diff,\n                            const void *stream);\n\nclass Pipeline {\n  public:\n    virtual ~Pipeline() = default;\n\n    virtual void trace_forward(const TraceSettings &settings,\n                               uint32_t num_points,\n                               const Vec3f *points,\n                               const void *attributes,\n                               uint32_t point_adjacency_size,\n                               const uint32_t *point_adjacency,\n                               const uint32_t *point_adjacency_offsets,\n                               uint32_t num_rays,\n                               const Ray *rays,\n                               const uint32_t *start_point_index,\n                               uint32_t num_depth_quantiles,\n                               const float *depth_quantiles,\n                               void *ray_rgba,\n                               float *quantile_dpeths,\n                               uint32_t *quantile_point_indices,\n                               uint32_t *num_intersections,\n                               void *point_contribution) = 0;\n\n    virtual void trace_backward(const TraceSettings &settings,\n                                uint32_t num_points,\n                                const Vec3f *points,\n                                const void *attributes,\n                                uint32_t point_adjacency_size,\n                                const uint32_t *point_adjacency,\n                                const uint32_t *point_adjacency_offsets,\n                                uint32_t num_rays,\n                                const Ray *rays,\n                                const uint32_t *start_point_index,\n                                uint32_t num_depth_quantiles,\n                                const float *depth_quantiles,\n                                const uint32_t *quantile_point_indices,\n                                const void *ray_rgba,\n                                const void *ray_rgba_grad,\n                                const float *depth_grad,\n                                const void *ray_error,\n                                Ray *ray_grad,\n                                Vec3f *points_grad,\n                                void *attribute_grad,\n                                void *point_error) = 0;\n\n    virtual void trace_visualization(const TraceSettings &settings,\n                                     const VisualizationSettings &vis_settings,\n                                     const Camera &camera,\n                                     CMapTable cmap_table,\n                                     uint32_t num_points,\n                                     uint32_t num_tets,\n                                     const void *points,\n                                     const void *attributes,\n                                     const void *point_adjacency,\n                                     const void *point_adjacency_offsets,\n                                     const void *adjacent_points,\n                                     uint32_t start_index,\n                                     uint64_t output_surface,\n                                     const void *stream = nullptr) = 0;\n\n    virtual void trace_benchmark(const TraceSettings &settings,\n                                 uint32_t num_points,\n                                 const Vec3f *points,\n                                 const void *attributes,\n                                 const uint32_t *point_adjacency,\n                                 const uint32_t *point_adjacency_offsets,\n                                 const Vec4h *adjacent_diff,\n                                 Camera camera,\n                                 const uint32_t *start_point_index,\n                                 uint32_t *ray_rgba) = 0;\n\n    virtual uint32_t attribute_dim() const = 0;\n\n    virtual ScalarType attribute_type() const = 0;\n};\n\nstd::shared_ptr<Pipeline> create_pipeline(int sh_degree, ScalarType attr_type);\n\n} // namespace radfoam"
  },
  {
    "path": "src/tracing/sh_utils.cuh",
    "content": "#pragma once\n\n#include \"../utils/geometry.h\"\n#include \"camera.h\"\n\nnamespace radfoam {\n\n__constant__ float C0 = 0.28209479177387814f;\n__constant__ float C1 = 0.4886025119029199f;\n__constant__ float C2[5] = {1.0925484305920792f,\n                            -1.0925484305920792f,\n                            0.31539156525252005f,\n                            -1.0925484305920792f,\n                            0.5462742152960396f};\n__constant__ float C3[7] = {-0.5900435899266435f,\n                            2.890611442640554f,\n                            -0.4570457994644658f,\n                            0.3731763325901154f,\n                            -0.4570457994644658f,\n                            1.445305721320277f,\n                            -0.5900435899266435f};\n__constant__ float C4[9] = {2.5033429417967046f,\n                            -1.7701307697799304f,\n                            0.9461746957575601f,\n                            -0.6690465435572892f,\n                            0.10578554691520431f,\n                            -0.6690465435572892f,\n                            0.47308734787878004f,\n                            -1.7701307697799304f,\n                            0.6258357354491761f};\n\nconstexpr int sh_dimension(int degree) { return (degree + 1) * (degree + 1); }\n\ntemplate <int degree>\n__device__ Vecf<sh_dimension(degree)> sh_coefficients(const Vec3f &dir) {\n    float x = dir[0];\n    float y = dir[1];\n    float z = dir[2];\n\n    Vecf<sh_dimension(degree)> sh = Vecf<sh_dimension(degree)>::Zero();\n\n    sh[0] = C0;\n\n    if (degree > 0) {\n        sh[1] = -C1 * y;\n        sh[2] = C1 * z;\n        sh[3] = -C1 * x;\n    }\n    float xx = x * x, yy = y * y, zz = z * z;\n    float xy = x * y, yz = y * z, xz = x * z;\n    if (degree > 1) {\n\n        sh[4] = C2[0] * xy;\n        sh[5] = C2[1] * yz;\n        sh[6] = C2[2] * (2.0f * zz - xx - yy);\n        sh[7] = C2[3] * xz;\n        sh[8] = C2[4] * (xx - yy);\n    }\n    if (degree > 2) {\n        sh[9] = C3[0] * y * (3.0f * xx - yy);\n        sh[10] = C3[1] * xy * z;\n        sh[11] = C3[2] * y * (4.0f * zz - xx - yy);\n        sh[12] = C3[3] * z * (2.0f * zz - 3.0f * xx - 3.0f * yy);\n        sh[13] = C3[4] * x * (4.0f * zz - xx - yy);\n        sh[14] = C3[5] * z * (xx - yy);\n        sh[15] = C3[6] * x * (xx - 3.0f * yy);\n    }\n\n    return sh;\n}\n\ntemplate <typename scalar, int degree>\n__device__ Vec3f load_sh_as_rgb(const Vecf<sh_dimension(degree)> &coeffs,\n                                const scalar *sh_rgb_vals) {\n    Vec3f rgb = Vec3f(0.5f, 0.5f, 0.5f);\n\n#pragma unroll\n    for (uint32_t i = 0; i < 3 * sh_dimension(degree); ++i) {\n        rgb[i % 3] += coeffs[i / 3] * (float)sh_rgb_vals[i];\n    }\n\n    return rgb.cwiseMax(0.0f);\n}\n\ntemplate <typename scalar, int degree>\n__device__ void write_rgb_grad_to_sh(const Vecf<sh_dimension(degree)> &coeffs,\n                                     Vec3f grad_rgb,\n                                     scalar *sh_rgb_grad) {\n    for (uint32_t i = 0; i < 3 * sh_dimension(degree); ++i) {\n        atomicAdd(sh_rgb_grad + i, (scalar)(coeffs[i / 3] * grad_rgb[i % 3]));\n    }\n}\n\ntemplate <typename attr_scalar, int sh_dim>\n__device__ Vec3<attr_scalar>\nforward_sh(uint32_t deg, Vec<attr_scalar, sh_dim> sh_vec, Vec3f dirs) {\n    float x = dirs[0];\n    float y = dirs[1];\n    float z = dirs[2];\n\n    constexpr int sh_vars = int(sh_dim / 3);\n    Eigen::Map<Eigen::Matrix<attr_scalar, 3, sh_vars>> sh_mat(sh_vec.data());\n\n    Vec3<attr_scalar> result = C0 * sh_mat.col(0);\n    if (deg > 0) {\n        result = result - C1 * y * sh_mat.col(1) + C1 * z * sh_mat.col(2) -\n                 C1 * x * sh_mat.col(3);\n    }\n\n    float xx = x * x, yy = y * y, zz = z * z;\n    float xy = x * y, yz = y * z, xz = x * z;\n    if (deg > 1) {\n        result = result + C2[0] * xy * sh_mat.col(4) +\n                 C2[1] * yz * sh_mat.col(5) +\n                 C2[2] * (2.0f * zz - xx - yy) * sh_mat.col(6) +\n                 C2[3] * xz * sh_mat.col(7) + C2[4] * (xx - yy) * sh_mat.col(8);\n    }\n    if (deg > 2) {\n        result =\n            result + C3[0] * y * (3.0f * xx - yy) * sh_mat.col(9) +\n            C3[1] * xy * z * sh_mat.col(10) +\n            C3[2] * y * (4.0f * zz - xx - yy) * sh_mat.col(11) +\n            C3[3] * z * (2.0f * zz - 3.0f * xx - 3.0f * yy) * sh_mat.col(12) +\n            C3[4] * x * (4.0f * zz - xx - yy) * sh_mat.col(13) +\n            C3[5] * z * (xx - yy) * sh_mat.col(14) +\n            C3[6] * x * (xx - 3.0f * yy) * sh_mat.col(15);\n    }\n\n    result = result.array() + 0.5f;\n    return result;\n}\n\ntemplate <typename attr_scalar, int sh_dim>\n__device__ Vec<attr_scalar, sh_dim>\nbackward_sh(uint32_t deg, Vec3<attr_scalar> pd_color, Vec3f dirs) {\n    float x = dirs[0];\n    float y = dirs[1];\n    float z = dirs[2];\n\n    constexpr int sh_vars = int(sh_dim / 3);\n    Eigen::Matrix<attr_scalar, 3, sh_vars> pd_sh;\n\n    pd_sh.col(0) = C0 * pd_color;\n    if (deg > 0) {\n        pd_sh.col(1) = -C1 * y * pd_color;\n        pd_sh.col(2) = C1 * z * pd_color;\n        pd_sh.col(3) = -C1 * x * pd_color;\n\n        if (deg > 1) {\n            float xx = x * x, yy = y * y, zz = z * z;\n            float xy = x * y, yz = y * z, xz = x * z;\n\n            pd_sh.col(4) = C2[0] * xy * pd_color;\n            pd_sh.col(5) = C2[1] * yz * pd_color;\n            pd_sh.col(6) = C2[2] * (2.0f * zz - xx - yy) * pd_color;\n            pd_sh.col(7) = C2[3] * xz * pd_color;\n            pd_sh.col(8) = C2[4] * (xx - yy) * pd_color;\n\n            if (deg > 2) {\n                pd_sh.col(9) = C3[0] * y * (3.0f * xx - yy) * pd_color;\n                pd_sh.col(10) = C3[1] * xy * z * pd_color;\n                pd_sh.col(11) = C3[2] * y * (4.0f * zz - xx - yy) * pd_color;\n                pd_sh.col(12) =\n                    C3[3] * z * (2.0f * zz - 3.0f * xx - 3.0f * yy) * pd_color;\n                pd_sh.col(13) = C3[4] * x * (4.0f * zz - xx - yy) * pd_color;\n                pd_sh.col(14) = C3[5] * z * (xx - yy) * pd_color;\n                pd_sh.col(15) = C3[6] * x * (xx - 3.0f * yy) * pd_color;\n            }\n        }\n    }\n\n    Eigen::Map<Vec<attr_scalar, sh_dim>> pd_sh_vector(pd_sh.data());\n    return pd_sh_vector;\n}\n\n} // namespace radfoam\n"
  },
  {
    "path": "src/tracing/tracing_utils.cuh",
    "content": "#pragma once\n\n#include \"../utils/geometry.h\"\n#include \"camera.h\"\n\nnamespace radfoam {\n\ntemplate <int block_size, int chunk_size, typename CellFunctor>\n__forceinline__ __device__ uint32_t\ntrace(const Ray &ray,\n      const Vec3f *__restrict__ points,\n      const uint32_t *__restrict__ point_adjacency,\n      const uint32_t *__restrict__ point_adjacency_offsets,\n      const Vec4h *__restrict__ adjacent_points,\n      uint32_t start_point,\n      uint32_t max_steps,\n      CellFunctor cell_functor) {\n    float t_0 = 0.0f;\n    uint32_t n = 0;\n\n    uint32_t current_point_idx = start_point;\n    Vec3f primal_point = points[current_point_idx];\n\n    for (;;) {\n        n++;\n        if (n > max_steps) {\n            break;\n        }\n\n        // Outer loop iterates through Voronoi cells\n        uint32_t point_adjacency_begin =\n            point_adjacency_offsets[current_point_idx];\n        uint32_t point_adjacency_end =\n            point_adjacency_offsets[current_point_idx + 1];\n\n        uint32_t num_faces = point_adjacency_end - point_adjacency_begin;\n        float t_1 = std::numeric_limits<float>::infinity();\n\n        uint32_t next_face = UINT32_MAX;\n        Vec3f next_point = Vec3f::Zero();\n\n        half2 chunk[chunk_size * 2];\n        for (uint32_t i = 0; i < num_faces; i += chunk_size) {\n#pragma unroll\n            for (uint32_t j = 0; j < chunk_size; ++j) {\n                chunk[2 * j] = reinterpret_cast<const half2 *>(\n                    adjacent_points + point_adjacency_begin + i + j)[0];\n                chunk[2 * j + 1] = reinterpret_cast<const half2 *>(\n                    adjacent_points + point_adjacency_begin + i + j)[1];\n            }\n\n#pragma unroll\n            for (uint32_t j = 0; j < chunk_size; ++j) {\n                Vec3f offset(__half2float(chunk[2 * j].x),\n                             __half2float(chunk[2 * j].y),\n                             __half2float(chunk[2 * j + 1].x));\n                Vec3f face_origin = primal_point + offset / 2.0f;\n                Vec3f face_normal = offset;\n                float dp = face_normal.dot(ray.direction);\n                float t = (face_origin - ray.origin).dot(face_normal) / dp;\n\n                if (dp > 0.0f && t < t_1 && (i + j) < num_faces) {\n                    t_1 = t;\n                    next_face = i + j;\n                }\n            }\n        }\n\n        if (next_face == UINT32_MAX) {\n            break;\n        }\n\n        uint32_t next_point_idx =\n            point_adjacency[point_adjacency_begin + next_face];\n        next_point = points[next_point_idx];\n\n        if (t_1 > t_0) {\n            if (!cell_functor(\n                    current_point_idx, t_0, t_1, primal_point, next_point)) {\n                break;\n            }\n        }\n        t_0 = fmaxf(t_0, t_1);\n        current_point_idx = next_point_idx;\n        primal_point = next_point;\n    }\n\n    return n;\n}\n\n__forceinline__ __device__ Vec3f cell_intersection_grad(\n    const Vec3f &primal_point, const Vec3f &opposite_point, const Ray &ray) {\n    Vec3f face_origin = (primal_point + opposite_point) / 2.0f;\n    Vec3f face_normal = (opposite_point - primal_point);\n\n    float num = (face_origin - ray.origin).dot(face_normal);\n    float dp = face_normal.dot(ray.direction);\n\n    Vec3f grad = num * ray.direction + dp * (ray.origin - primal_point);\n    grad /= dp * dp;\n\n    return grad;\n}\n\ninline RADFOAM_HD uint32_t make_rgba8(float r, float g, float b, float a) {\n    r = std::max(0.0f, std::min(1.0f, r));\n    g = std::max(0.0f, std::min(1.0f, g));\n    b = std::max(0.0f, std::min(1.0f, b));\n    a = std::max(0.0f, std::min(1.0f, a));\n    int ri = static_cast<int>(r * 255.0f);\n    int gi = static_cast<int>(g * 255.0f);\n    int bi = static_cast<int>(b * 255.0f);\n    int ai = static_cast<int>(a * 255.0f);\n    return (ai << 24) | (bi << 16) | (gi << 8) | ri;\n}\n\ninline __device__ Vec3f colormap(float v,\n                                 ColorMap map,\n                                 const CMapTable &cmap_table) {\n    int map_len = cmap_table.sizes[map];\n    const Vec3f *map_vals =\n        reinterpret_cast<const Vec3f *>(cmap_table.data[map]);\n\n    int i0 = static_cast<int>(v * (map_len - 1));\n    int i1 = i0 + 1;\n    float t = v * (map_len - 1) - i0;\n    i0 = max(0, min(i0, map_len - 1));\n    i1 = max(0, min(i1, map_len - 1));\n    return map_vals[i0] * (1.0f - t) + map_vals[i1] * t;\n}\n\n} // namespace radfoam"
  },
  {
    "path": "src/utils/batch_fetcher.cpp",
    "content": "#include <atomic>\n#include <cstring>\n#include <exception>\n#include <iostream>\n#include <thread>\n#include <vector>\n\n#include <atomic_queue/atomic_queue.h>\n\n#define THRUST_HOST_SYSTEM THRUST_HOST_SYSTEM_TBB\n#include <thrust/execution_policy.h>\n#include <thrust/for_each.h>\n#include <thrust/iterator/counting_iterator.h>\n\n#include \"batch_fetcher.h\"\n#include \"cuda_helpers.h\"\n#include \"random.h\"\n\nnamespace radfoam {\n\nconstexpr int buffer_size = 4;\n\nstruct Batch {\n    CUdeviceptr data;\n    CUevent data_ready_event;\n};\n\nclass BatchFetcherImpl : public BatchFetcher {\n  public:\n    BatchFetcherImpl(const uint8_t *data,\n                     size_t num_bytes,\n                     size_t stride,\n                     size_t batch_size,\n                     bool shuffle)\n        : worker_exception(nullptr), done(false) {\n\n        CUcontext context;\n        cuda_check(cuCtxGetCurrent(&context));\n\n        if (context == nullptr) {\n            throw std::runtime_error(\"No CUDA context found\");\n        }\n\n        worker = std::thread([=] {\n            try {\n                size_t num_elemnts = num_bytes / stride;\n                if (num_elemnts > (size_t)__UINT32_MAX__) {\n                    throw std::runtime_error(\"Too many elements\");\n                }\n                uint32_t batch_idx = 0;\n\n                cuda_check(cuCtxSetCurrent(context));\n\n                CUstream stream;\n\n                std::vector<uint8_t> cpu_batch_buffer[buffer_size];\n                CUdeviceptr gpu_batch_buffer[buffer_size];\n                CUevent events[buffer_size];\n\n                cuda_check(cuStreamCreate(&stream, CU_STREAM_NON_BLOCKING));\n\n                auto upload_batch = [&](int i) {\n                    auto copy_element = [&](int j) {\n                        size_t idx;\n                        if (shuffle) {\n                            auto rng = make_rng(batch_idx * batch_size + j);\n                            idx = randint(rng, 0, num_elemnts);\n                        } else {\n                            idx = (batch_idx * batch_size + j) % num_elemnts;\n                        }\n                        memcpy(cpu_batch_buffer[i].data() + j * stride,\n                               data + idx * stride,\n                               stride);\n                    };\n                    thrust::for_each(thrust::host,\n                                     thrust::counting_iterator<int>(0),\n                                     thrust::counting_iterator<int>(batch_size),\n                                     copy_element);\n                    batch_idx += 1;\n                    cuda_check(cuMemcpyHtoDAsync(gpu_batch_buffer[i],\n                                                 cpu_batch_buffer[i].data(),\n                                                 batch_size * stride,\n                                                 stream));\n                    cuda_check(cuEventRecord(events[i], stream));\n\n                    return Batch{gpu_batch_buffer[i], events[i]};\n                };\n\n                for (int i = 0; i < buffer_size; ++i) {\n                    cpu_batch_buffer[i].resize(batch_size * stride);\n                    cuda_check(\n                        cuMemAlloc(&gpu_batch_buffer[i], batch_size * stride));\n                    cuda_check(\n                        cuEventCreate(&events[i], CU_EVENT_BLOCKING_SYNC));\n                }\n\n                int i = 0;\n                while (!this->done) {\n                    auto batch = upload_batch(i);\n                    while (!queue.try_push(batch) && !this->done) {\n                        std::this_thread::yield();\n                    }\n                    i = (i + 1) % buffer_size;\n                }\n\n                // Free resources\n                cuda_check(cuStreamSynchronize(stream));\n                for (int i = 0; i < buffer_size; i++) {\n                    cuda_check(cuMemFree(gpu_batch_buffer[i]));\n                    cuda_check(cuEventDestroy(events[i]));\n                }\n                cuda_check(cuStreamDestroy(stream));\n            } catch (...) {\n                this->worker_exception = std::current_exception();\n                this->done = true;\n            }\n        });\n    }\n\n    ~BatchFetcherImpl() {\n        done = true;\n        worker.join();\n    }\n\n    void *next() override {\n        Batch batch = {};\n        while (!done && !queue.try_pop(batch)) {\n            std::this_thread::yield();\n        }\n        if (done) {\n            worker.join();\n            std::rethrow_exception(worker_exception);\n        }\n        cuda_check(cuEventSynchronize(batch.data_ready_event));\n        return reinterpret_cast<void *>(batch.data);\n    }\n\n  private:\n    std::exception_ptr worker_exception;\n    std::thread worker;\n    std::atomic_bool done;\n    atomic_queue::AtomicQueue2<Batch, buffer_size - 2> queue;\n};\n\nstd::unique_ptr<BatchFetcher> create_batch_fetcher(const void *data,\n                                                   size_t num_bytes,\n                                                   size_t stride,\n                                                   size_t batch_size,\n                                                   bool shuffle) {\n    return std::make_unique<BatchFetcherImpl>(\n        static_cast<const uint8_t *>(data),\n        num_bytes,\n        stride,\n        batch_size,\n        shuffle);\n}\n\n} // namespace radfoam"
  },
  {
    "path": "src/utils/batch_fetcher.h",
    "content": "#pragma once\n\n#include <memory>\n\nnamespace radfoam {\n\nclass BatchFetcher {\n  public:\n    virtual ~BatchFetcher() = default;\n\n    virtual void *next() = 0;\n};\n\nstd::unique_ptr<BatchFetcher> create_batch_fetcher(const void *data,\n                                                   size_t num_bytes,\n                                                   size_t stride,\n                                                   size_t batch_size,\n                                                   bool shuffle);\n\n} // namespace radfoam"
  },
  {
    "path": "src/utils/common_kernels.cuh",
    "content": "#pragma once\n\n#include <iostream>\n\n#include \"cuda_helpers.h\"\n\n#include <cub/iterator/arg_index_input_iterator.cuh>\n#include <cub/iterator/counting_input_iterator.cuh>\n#include <cub/iterator/discard_output_iterator.cuh>\n\n#include \"unenumerate_iterator.cuh\"\n\nnamespace radfoam {\n\ntemplate <typename InputIterator, typename UnaryFunction>\n__global__ void for_n_kernel(InputIterator begin, size_t n, UnaryFunction f) {\n    size_t i = blockIdx.x * blockDim.x + threadIdx.x;\n    size_t stride = gridDim.x * blockDim.x;\n    while (i < n) {\n        f(begin[i]);\n        i += stride;\n    }\n}\n\ntemplate <int block_size, typename Kernel, typename... Args>\nvoid launch_kernel_1d(Kernel kernel,\n                      size_t n,\n                      const void *stream,\n                      Args... args) {\n    if (n == 0) {\n        return;\n    }\n    size_t num_blocks = (n + block_size - 1) / block_size;\n    if (stream) {\n        cudaStream_t s = *reinterpret_cast<const cudaStream_t *>(stream);\n        kernel<<<num_blocks, block_size, 0, s>>>(args...);\n    } else {\n        kernel<<<num_blocks, block_size>>>(args...);\n    }\n    cuda_check(cudaGetLastError());\n}\n\ntemplate <int block_size, typename InputIterator, typename UnaryFunction>\nvoid for_n_b(InputIterator begin,\n             size_t n,\n             UnaryFunction f,\n             bool strided = false,\n             const void *stream = nullptr) {\n    size_t num_threads = n;\n    if (strided) {\n        int mpc;\n        cuda_check(\n            cudaDeviceGetAttribute(&mpc, cudaDevAttrMultiProcessorCount, 0));\n        num_threads = block_size * mpc;\n    }\n\n    launch_kernel_1d<block_size>(for_n_kernel<InputIterator, UnaryFunction>,\n                                 num_threads,\n                                 stream,\n                                 begin,\n                                 n,\n                                 f);\n}\n\ntemplate <typename InputIterator, typename UnaryFunction>\nvoid for_n(InputIterator begin,\n           size_t n,\n           UnaryFunction f,\n           bool strided = false,\n           const void *stream = nullptr) {\n    for_n_b<256>(begin, n, f, strided, stream);\n}\n\ntemplate <typename InputIterator, typename UnaryFunction>\nvoid for_range(InputIterator begin,\n               InputIterator end,\n               UnaryFunction f,\n               bool strided = false,\n               const void *stream = nullptr) {\n    size_t n = end - begin;\n    for_n(begin, n, f, strided, stream);\n}\n\ntemplate <typename InputIterator,\n          typename OutputIterator,\n          typename UnaryFunction>\nstruct TransformFunctor {\n    InputIterator begin;\n    OutputIterator result;\n    UnaryFunction f;\n\n    __device__ void operator()(decltype(*begin) x) {\n        size_t i = blockIdx.x * blockDim.x + threadIdx.x;\n        result[i] = f(x);\n    }\n};\n\ntemplate <typename InputIterator,\n          typename OutputIterator,\n          typename UnaryFunction>\nvoid transform_range(InputIterator begin,\n                     InputIterator end,\n                     OutputIterator result,\n                     UnaryFunction f,\n                     bool strided = false,\n                     const void *stream = nullptr) {\n    size_t n = end - begin;\n    TransformFunctor<InputIterator, OutputIterator, UnaryFunction> func = {\n        begin, result, f};\n    for_n(begin, n, func, strided, stream);\n}\n\ntemplate <typename InputIterator, typename OutputIterator>\nvoid copy_range(InputIterator begin,\n                InputIterator end,\n                OutputIterator result,\n                bool strided = false,\n                const void *stream = nullptr) {\n    transform_range(\n        begin,\n        end,\n        result,\n        [] __device__(auto x) { return x; },\n        strided,\n        stream);\n}\n\ninline cub::CountingInputIterator<uint32_t> u32zero() {\n    return cub::CountingInputIterator<uint32_t>(0);\n}\n\ninline cub::CountingInputIterator<uint64_t> u64zero() {\n    return cub::CountingInputIterator<uint64_t>(0);\n}\n\ntemplate <typename T>\ninline cub::ArgIndexInputIterator<T *> enumerate(T *begin) {\n    return cub::ArgIndexInputIterator<T *>(begin);\n}\n\ntemplate <typename T>\ninline UnenumerateIterator<T> unenumerate(T *begin) {\n    return UnenumerateIterator<T>(begin);\n}\n\ninline cub::DiscardOutputIterator<> discard() {\n    return cub::DiscardOutputIterator();\n}\n\n} // namespace radfoam"
  },
  {
    "path": "src/utils/cuda_array.h",
    "content": "#pragma once\n\n#include <iostream>\n#include <limits>\n#include <memory>\n#include <vector>\n\n#include \"cuda_helpers.h\"\n#include \"typing.h\"\n\n#define CUB_CALL(call)                                                         \\\n    {                                                                          \\\n        size_t temp_bytes = 0;                                                 \\\n        void *temp_data;                                                       \\\n        CUDAArray<uint8_t> cub_temp_buffer;                                    \\\n        for (temp_data = nullptr;;) {                                          \\\n            cuda_check(call);                                                  \\\n            if (temp_data)                                                     \\\n                break;                                                         \\\n            else {                                                             \\\n                cub_temp_buffer.resize(temp_bytes);                            \\\n                temp_data = cub_temp_buffer.begin();                           \\\n            }                                                                  \\\n        }                                                                      \\\n    }\n\nnamespace radfoam {\n\nstruct OpaqueBuffer {\n    virtual ~OpaqueBuffer() = default;\n\n    virtual void *data() = 0;\n};\n\nstd::unique_ptr<OpaqueBuffer> allocate_buffer(size_t bytes);\n\n/// @brief RAII wrapper for CUDA array\ntemplate <typename T>\nclass CUDAArray {\n    template <typename U>\n    friend class CUDAArray;\n\n  private:\n    CUdeviceptr begin_ptr;\n    CUdeviceptr end_ptr;\n    std::unique_ptr<OpaqueBuffer> buffer;\n\n  public:\n    /// @brief Construct an empty CUDA array\n    CUDAArray() : begin_ptr(0), end_ptr(0), buffer(nullptr) {}\n\n    /// @brief Construct a CUDA array of a given size\n    CUDAArray(size_t size) {\n        if (size == 0) {\n            begin_ptr = 0;\n            end_ptr = 0;\n            buffer = nullptr;\n            return;\n        }\n        buffer = allocate_buffer(size * sizeof(T));\n        begin_ptr = reinterpret_cast<CUdeviceptr>(buffer->data());\n        end_ptr = begin_ptr + (size * sizeof(T));\n    }\n\n    CUDAArray(const CUDAArray &other) = delete;\n\n    CUDAArray(CUDAArray &&other) {\n        begin_ptr = other.begin_ptr;\n        end_ptr = other.end_ptr;\n        other.begin_ptr = 0;\n        other.end_ptr = 0;\n        buffer = std::move(other.buffer);\n    }\n\n    ~CUDAArray() = default;\n\n    CUDAArray &operator=(const CUDAArray &other) = delete;\n\n    CUDAArray &operator=(CUDAArray &&other) {\n        begin_ptr = other.begin_ptr;\n        end_ptr = other.end_ptr;\n        other.begin_ptr = 0;\n        other.end_ptr = 0;\n        buffer = std::move(other.buffer);\n        return *this;\n    }\n\n    template <typename U>\n    CUDAArray(CUDAArray<U> &&other) {\n        begin_ptr = other.begin_ptr;\n        end_ptr = other.end_ptr;\n        other.begin_ptr = 0;\n        other.end_ptr = 0;\n        buffer = std::move(other.buffer);\n    }\n\n    /// @brief Get a pointer to the beginning of the array\n    T *begin() { return reinterpret_cast<T *>(begin_ptr); }\n\n    /// @brief Get a pointer to the end of the array\n    T *end() {\n        size_t size_bytes = end_ptr - begin_ptr;\n        size_t elements = size_bytes / sizeof(T);\n        return reinterpret_cast<T *>(begin_ptr) + elements;\n    }\n\n    /// @brief Get a pointer to the beginning of the array\n    const T *begin() const { return reinterpret_cast<const T *>(begin_ptr); }\n\n    /// @brief Get a pointer to the end of the array\n    const T *end() const {\n        size_t size_bytes = end_ptr - begin_ptr;\n        size_t elements = size_bytes / sizeof(T);\n        return reinterpret_cast<const T *>(begin_ptr) + elements;\n    }\n\n    /// @brief Get a pointer to the beginning of the array as a different type\n    template <typename U>\n    U *begin_as() {\n        return reinterpret_cast<U *>(begin_ptr);\n    }\n\n    /// @brief Get a pointer to the end of the array as a different type\n    template <typename U>\n    U *end_as() {\n        size_t size_bytes = end_ptr - begin_ptr;\n        size_t elements = size_bytes / sizeof(T);\n        return reinterpret_cast<U *>(reinterpret_cast<const T *>(begin_ptr) +\n                                     elements);\n    }\n\n    /// @brief Get a pointer to the beginning of the array as a different type\n    template <typename U>\n    const U *begin_as() const {\n        return reinterpret_cast<const U *>(begin_ptr);\n    }\n\n    /// @brief Get a pointer to the end of the array as a different type\n    template <typename U>\n    const U *end_as() const {\n        size_t size_bytes = end_ptr - begin_ptr;\n        size_t elements = size_bytes / sizeof(T);\n        return reinterpret_cast<const U *>(\n            reinterpret_cast<const T *>(begin_ptr) + elements);\n    }\n\n    /// @brief Get the number of elements in the array\n    size_t size() const { return (end_ptr - begin_ptr) / sizeof(T); }\n\n    /// @brief Set the number of elements in the array\n    /// @param size The new size of the array\n    /// @param preserve_content If true, the elements currently in the array\n    /// will be copied to the beginning of the new array, up to the minimum of\n    /// the old and new sizes\n    void resize(size_t size, bool preserve_content = false) {\n        if (size == this->size()) {\n            return;\n        }\n        if (begin_ptr) {\n            auto new_buffer = allocate_buffer(size * sizeof(T));\n            CUdeviceptr new_begin_ptr =\n                reinterpret_cast<CUdeviceptr>(new_buffer->data());\n            if (preserve_content) {\n                if (size > this->size()) {\n                    cuda_check(cuMemcpyDtoD(\n                        new_begin_ptr, begin_ptr, this->size() * sizeof(T)));\n                } else {\n                    cuda_check(cuMemcpyDtoD(\n                        new_begin_ptr, begin_ptr, size * sizeof(T)));\n                }\n            }\n            buffer = std::move(new_buffer);\n            begin_ptr = new_begin_ptr;\n            end_ptr = begin_ptr + (size * sizeof(T));\n        } else {\n            *this = CUDAArray(size);\n        }\n    }\n\n    /// @brief Expand the array to at least a given size\n    /// @param size The minimum size of the array\n    /// @param preserve_content If true, the elements currently in the array\n    /// will be copied to the beginning of the new array, up to the minimum of\n    /// the old and new sizes\n    /// @param round_up If true, the size will be rounded up to the nearest\n    /// power of 2\n    void\n    expand(size_t size, bool preserve_content = false, bool round_up = true) {\n        if (size > this->size()) {\n            if (round_up)\n                size = pow2_round_up(size);\n            resize(size, preserve_content);\n        }\n    }\n\n    void clear() {\n        begin_ptr = 0;\n        end_ptr = 0;\n        buffer = nullptr;\n    }\n};\n\n} // namespace radfoam\n"
  },
  {
    "path": "src/utils/cuda_helpers.h",
    "content": "#pragma once\n\n#include <functional>\n#include <stdexcept>\n\n#include <GL/gl3w.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n\nnamespace radfoam {\n\ninline void cuda_check_fn(cudaError_t err, int line, const char *file) {\n    if (err != cudaSuccess) {\n        std::string msg = \"CUDA call at \" + std::string(file) + \":\" +\n                          std::to_string(line) + \" failed: \";\n        msg = msg + cudaGetErrorString(err);\n        throw std::runtime_error(msg);\n    }\n}\n\ninline void cuda_check_fn(CUresult err, int line, const char *file) {\n    if (err != CUDA_SUCCESS) {\n        const char *msg;\n        cuGetErrorString(err, &msg);\n        throw std::runtime_error(std::string(\"CUDA call at \") + file + \":\" +\n                                 std::to_string(line) + \" failed: \" + msg);\n    }\n}\n\n#define cuda_check(call) radfoam::cuda_check_fn(call, __LINE__, __FILE__)\n\ninline void gl_check_fn(GLenum err, int line, const char *file) {\n    if (err != GL_NO_ERROR) {\n        throw std::runtime_error(\"OpenGL call at \" + std::string(file) + \":\" +\n                                 std::to_string(line) + \" failed\");\n    }\n}\n\n#define gl_check(call)                                                         \\\n    call;                                                                      \\\n    radfoam::gl_check_fn(glGetError(), __LINE__, __FILE__)\n\ninline void global_cuda_init() {\n    cuda_check(cuInit(0));\n    cuda_check(cudaDeviceSetLimit(cudaLimitMallocHeapSize, 1ul << 29ul));\n}\n\n} // namespace radfoam\n"
  },
  {
    "path": "src/utils/geometry.h",
    "content": "#pragma once\n\n#include <float.h>\n\n#define EIGEN_MPL2_ONLY\n#include <Eigen/Core>\n#include <Eigen/Geometry>\n\n#include <cuda_runtime.h>\n\n#include \"random.h\"\n#include \"typing.h\"\n\nnamespace radfoam {\n\ntemplate <typename scalar, int dim>\nusing Vec = Eigen::Matrix<scalar, dim, 1>;\n\ntemplate <typename scalar>\nusing Vec2 = Eigen::Matrix<scalar, 2, 1>;\n\ntemplate <typename scalar>\nusing Vec3 = Eigen::Matrix<scalar, 3, 1>;\n\ntemplate <typename scalar>\nusing Vec4 = Eigen::Matrix<scalar, 4, 1>;\n\ntemplate <typename scalar, int rows, int cols>\nusing Mat = Eigen::Matrix<scalar, rows, cols>;\n\ntemplate <typename scalar>\nusing Mat3 = Eigen::Matrix<scalar, 3, 3>;\n\ntemplate <typename scalar>\nusing Mat4 = Eigen::Matrix<scalar, 4, 4>;\n\ntemplate <int dim>\nusing Vecf = Vec<float, dim>;\n\nusing Vec2f = Vec2<float>;\nusing Vec3f = Vec3<float>;\nusing Vec4f = Vec4<float>;\n\nusing Mat3f = Mat3<float>;\nusing Mat4f = Mat4<float>;\n\ntemplate <int dim>\nusing Vecd = Vec<double, dim>;\n\nusing Vec2d = Vec2<double>;\nusing Vec3d = Vec3<double>;\nusing Vec4d = Vec4<double>;\n\nusing Mat3d = Mat3<double>;\nusing Mat4d = Mat4<double>;\n\ntemplate <int dim>\nusing Vech = Vec<__half, dim>;\n\nusing Vec2h = Vec2<__half>;\nusing Vec3h = Vec3<__half>;\nusing Vec4h = Vec4<__half>;\n\nusing Mat3h = Mat3<__half>;\nusing Mat4h = Mat4<__half>;\n\ntemplate <int dim>\nusing Veci = Vec<int32_t, dim>;\n\nusing Vec2i = Vec2<int32_t>;\nusing Vec3i = Vec3<int32_t>;\nusing Vec4i = Vec4<int32_t>;\n\nusing Mat3i = Mat<int32_t, 3, 3>;\nusing Mat4i = Mat<int32_t, 4, 4>;\n\ntemplate <int dim>\nusing Vecl = Vec<int64_t, dim>;\n\nusing Vec2l = Vec2<int64_t>;\nusing Vec3l = Vec3<int64_t>;\nusing Vec4l = Vec4<int64_t>;\n\nusing Mat3l = Mat<int64_t, 3, 3>;\nusing Mat4l = Mat<int64_t, 4, 4>;\n\n/// @brief A default-initializable matrix type that can be dereferenced to an\n/// Eigen matrix\ntemplate <typename scalar, int rows, int cols>\nstruct PODMat {\n    scalar data[rows * cols];\n\n    PODMat() = default;\n\n    RADFOAM_HD PODMat(const Eigen::Matrix<scalar, rows, cols> &mat) {\n        memcpy(data, mat.data(), sizeof(data));\n    }\n\n    RADFOAM_HD Eigen::Matrix<scalar, rows, cols> &operator*() {\n        return *reinterpret_cast<Eigen::Matrix<scalar, rows, cols> *>(data);\n    }\n\n    RADFOAM_HD const Eigen::Matrix<scalar, rows, cols> &operator*() const {\n        return *reinterpret_cast<const Eigen::Matrix<scalar, rows, cols> *>(\n            data);\n    }\n\n    RADFOAM_HD Eigen::Matrix<scalar, rows, cols> *operator->() {\n        return reinterpret_cast<Eigen::Matrix<scalar, rows, cols> *>(data);\n    }\n\n    RADFOAM_HD const Eigen::Matrix<scalar, rows, cols> *operator->() const {\n        return reinterpret_cast<const Eigen::Matrix<scalar, rows, cols> *>(\n            data);\n    }\n};\n\ntemplate <typename scalar>\nusing CVec2 = PODMat<scalar, 2, 1>;\n\ntemplate <typename scalar>\nusing CVec3 = PODMat<scalar, 3, 1>;\n\ntemplate <typename scalar>\nusing CVec4 = PODMat<scalar, 4, 1>;\n\ntemplate <typename scalar>\nusing CMat3 = PODMat<scalar, 3, 3>;\n\ntemplate <typename scalar>\nusing CMat4 = PODMat<scalar, 4, 4>;\n\nusing CVec2f = CVec2<float>;\nusing CVec3f = CVec3<float>;\nusing CVec4f = CVec4<float>;\n\nusing CMat3f = CMat3<float>;\nusing CMat4f = CMat4<float>;\n\n#ifdef __CUDACC__\ntemplate <typename vec>\n__device__ void atomic_add_vec(vec *dst, const vec &src) {\n    for (int i = 0; i < src.size(); ++i) {\n        atomicAdd(&((*dst)[i]), src[i]);\n    }\n}\n#endif\n\n/// @brief Generate a random 3-vector with each component in the range [0, 1]\ninline RADFOAM_HD Vec3f rand3(RNGState &rngstate) {\n    return Vec3f(rand(rngstate), rand(rngstate), rand(rngstate));\n}\n\n/// @brief Generate a random 3-vector from a unit normal distribution\ninline RADFOAM_HD Vec3f randn3(RNGState &rngstate) {\n    return Vec3f(randn(rngstate), randn(rngstate), randn(rngstate));\n}\n\n/// @brief Generate a random unit 3-vector from a uniform distribution on S^2\ninline RADFOAM_HD Vec3f rand_unit3(RNGState &rngstate) {\n    float theta = 2 * M_PIf * rand(rngstate);\n    float z = 2 * rand(rngstate) - 1;\n    float r = sqrtf(1 - z * z);\n    return Vec3f(r * cosf(theta), r * sinf(theta), z);\n}\n\n/// @brief Enum representing the result of an intersection test\nenum class IntersectionResult {\n    Inside,\n    Outside,\n    Intersecting,\n};\n\n/// @brief Compare two sets of n elements for equality regardless of order\ntemplate <int n, typename T>\nRADFOAM_HD bool set_equal(const T *a, const T *b) {\n    bool equal = true;\n#pragma unroll\n    for (int i = 0; i < n; i++) {\n        bool found = false;\n#pragma unroll\n        for (int j = 0; j < n; j++) {\n            found |= (a[i] == b[j]);\n        }\n        equal &= found;\n    }\n    return equal;\n}\n\n/// @brief Check if a set of n elements contains a given element\ntemplate <int n, typename T>\nRADFOAM_HD bool set_contains(const T *a, const T &b) {\n    bool found = false;\n#pragma unroll\n    for (int i = 0; i < n; i++) {\n        found |= (a[i] == b);\n    }\n    return found;\n}\n\n/// @brief Sort an array of n elements in place\ntemplate <int n, typename T>\nRADFOAM_HD void sort_in_place(T *a) {\n#pragma unroll\n    for (int i = 0; i < n; i++) {\n#pragma unroll\n        for (int j = i + 1; j < n; j++) {\n            if (a[j] < a[i]) {\n                swap(a[i], a[j]);\n            }\n        }\n    }\n}\n\n/// @brief Compare two sets of n elements lexicographically\ntemplate <int n, typename T>\nRADFOAM_HD bool set_less(const T *a, const T *b) {\n    T a_sorted[n];\n    T b_sorted[n];\n    memcpy(a_sorted, a, n * sizeof(T));\n    memcpy(b_sorted, b, n * sizeof(T));\n    sort_in_place<n>(a_sorted);\n    sort_in_place<n>(b_sorted);\n    for (int i = 0; i < n; i++) {\n        if (a_sorted[i] < b_sorted[i]) {\n            return true;\n        } else if (a_sorted[i] > b_sorted[i]) {\n            return false;\n        }\n    }\n    return false;\n}\n\n/// @brief Check the parity of a permutation\ntemplate <int n, typename T>\nRADFOAM_HD bool permutation_parity(const T *perm) {\n    int parity = 0;\n#pragma unroll\n    for (int i = 0; i < n; i++) {\n#pragma unroll\n        for (int j = i + 1; j < n; j++) {\n            parity += (perm[j] < perm[i]);\n        }\n    }\n    return parity % 2 == 0;\n}\n\n/// @brief Perform a binary search on a sorted sequence\n/// @return An iterator to an element in the sequence that is equal to value, or\n/// the end iterator if no such element exists\ntemplate <typename Iter>\nRADFOAM_HD Iter binary_search(Iter begin,\n                              Iter end,\n                              const decltype(*begin) &value) {\n    Iter low = begin;\n    Iter high = end;\n    while (low < high) {\n        Iter mid = low + (high - low) / 2;\n        if (*mid < value) {\n            low = mid + 1;\n        } else {\n            high = mid;\n        }\n    }\n    if (low < end && *low == value) {\n        return low;\n    } else {\n        return end;\n    }\n}\n\n/// @brief Compute the Morton code of a 3D point\ninline RADFOAM_HD uint32_t morton_code(const Vec3i &coords) {\n    uint32_t code = 0;\n#pragma unroll\n    for (uint32_t i = 0; i < 10; i++) {\n        code |= ((coords[0] >> i) & 1) << (3 * i);\n        code |= ((coords[1] >> i) & 1) << (3 * i + 1);\n        code |= ((coords[2] >> i) & 1) << (3 * i + 2);\n    }\n    return code;\n}\n\n/// @brief Compute the inverse Morton code of a 3D point\ninline RADFOAM_HD Vec3i inverse_morton_code(uint32_t code) {\n    Vec3i coords(0, 0, 0);\n#pragma unroll\n    for (uint32_t i = 0; i < 10; i++) {\n        coords[0] |= ((code >> (3 * i)) & 1) << i;\n        coords[1] |= ((code >> (3 * i + 1)) & 1) << i;\n        coords[2] |= ((code >> (3 * i + 2)) & 1) << i;\n    }\n    return coords;\n}\n\n/// @brief An axis-aligned bounding box\ntemplate <typename scalar>\nstruct AABB {\n    Vec3<scalar> min;\n    Vec3<scalar> max;\n\n    AABB() = default;\n\n    RADFOAM_HD AABB(Vec3<scalar> min, Vec3<scalar> max) : min(min), max(max) {}\n\n    template <typename other_scalar>\n    RADFOAM_HD AABB(const AABB<other_scalar> &other)\n        : min(other.min.template cast<scalar>()),\n          max(other.max.template cast<scalar>()) {}\n\n    /// @brief Computing the common bounding box of two AABBs\n    RADFOAM_HD AABB merge(const AABB &other) const {\n        return AABB(min.cwiseMin(other.min), max.cwiseMax(other.max));\n    }\n\n    /// @brief Query the SDF of the AABB at a given point\n    RADFOAM_HD scalar sdf(const Vec3<scalar> &p) const {\n        // Calculate the distance to the nearest point inside the AABB\n        Vec3<scalar> d =\n            (min - p).cwiseMax(Vec3<scalar>::Zero()).cwiseMax(p - max);\n\n        // Calculate the signed distance\n        scalar out_dist = d.norm();\n        scalar in_dist = std::min(max.x() - p.x(), p.x() - min.x());\n        in_dist = std::min(in_dist, std::min(max.y() - p.y(), p.y() - min.y()));\n        in_dist = std::min(in_dist, std::min(max.z() - p.z(), p.z() - min.z()));\n\n        return out_dist > scalar(1e-6) ? out_dist : -in_dist;\n    }\n\n    /// @brief Check if the AABB intersects a sphere\n    /// @param center The center of the sphere\n    /// @param radius The radius of the sphere\n    ///\n    /// @returns IntersectionResult::Outside indicates that the AABB is\n    /// entirely outside the sphere, IntersectionResult::Inside indicates that\n    /// the AABB is entirely inside the sphere, and\n    /// IntersectionResult::Intersecting indicates that the AABB intersects the\n    /// sphere.\n    RADFOAM_HD IntersectionResult intersects_sphere(const Vec3<scalar> &center,\n                                                    scalar radius) const {\n        scalar sdf_val = sdf(center);\n        if (sdf_val > radius) {\n            return IntersectionResult::Outside;\n        } else if (sdf_val < -radius) {\n            return IntersectionResult::Inside;\n        } else {\n            return IntersectionResult::Intersecting;\n        }\n    }\n};\n\n/// @brief A triangle represented by indices of its vertices in a point set\nstruct IndexedTriangle {\n    uint32_t vertices[3];\n\n    RADFOAM_HD IndexedTriangle() {}\n\n    RADFOAM_HD IndexedTriangle(uint32_t i0, uint32_t i1, uint32_t i2) {\n        vertices[0] = i0;\n        vertices[1] = i1;\n        vertices[2] = i2;\n    }\n\n    __device__ __forceinline__ uint32_t hash() const {\n        return mix(vertices[0]) ^ mix(vertices[1]) ^ mix(vertices[2]);\n    }\n\n    RADFOAM_HD friend bool operator==(const IndexedTriangle &a,\n                                      const IndexedTriangle &b) {\n        return set_equal<3>(a.vertices, b.vertices);\n    }\n\n    RADFOAM_HD friend bool operator!=(const IndexedTriangle &a,\n                                      const IndexedTriangle &b) {\n        return !set_equal<3>(a.vertices, b.vertices);\n    }\n\n    RADFOAM_HD friend bool operator<(const IndexedTriangle &a,\n                                     const IndexedTriangle &b) {\n        return set_less<3>(a.vertices, b.vertices);\n    }\n\n    RADFOAM_HD bool is_valid() {\n        return (vertices[0] < UINT32_MAX) && (vertices[1] < UINT32_MAX) &&\n               (vertices[2] < UINT32_MAX);\n    }\n\n    /// @brief Compute the normal vector of the triangle given the point set\n    template <typename scalar>\n    RADFOAM_HD Vec3<scalar> normal(const Vec3<scalar> &v0,\n                                   const Vec3<scalar> &v1,\n                                   const Vec3<scalar> &v2) const {\n        return (v1 - v0).cross(v2 - v1).normalized();\n    }\n\n    /// @brief Compute barycentric coordinates given a new point\n    template <typename scalar>\n    RADFOAM_HD Vec3f barycentric_coords(const Vec3<scalar> *points,\n                                        const Vec3f &new_point) {\n        Vec3<scalar> p0 = points[vertices[0]];\n        Vec3<scalar> p1 = points[vertices[1]];\n        Vec3<scalar> p2 = points[vertices[2]];\n\n        Vec3<scalar> AB = p1 - p0;\n        Vec3<scalar> AC = p2 - p0;\n        Vec3<scalar> BC = p2 - p1;\n        Vec3<scalar> AP = new_point - p0;\n        Vec3<scalar> BP = new_point - p1;\n\n        float areaABC = AB.cross(AC).norm();\n        float areaABP = AB.cross(AP).norm();\n        float areaACP = AC.cross(AP).norm();\n        float areaBCP = BC.cross(BP).norm();\n\n        float beta = areaACP / (areaABC + 1e-8f);\n        float gamma = areaABP / (areaABC + 1e-8f);\n        float alpha = areaBCP / (areaABC + 1e-8f);\n\n        return Vec3f(alpha, beta, gamma);\n    }\n\n    /// @brief Compute interpolated attributes given a new point\n    template <typename scalar, int dim>\n    RADFOAM_HD Vec<scalar, dim + 1>\n    interpolated_attributes(const Vec<scalar, dim + 1> *attributes,\n                            const Vec3f &barycentrics) {\n        Vec<scalar, dim + 1> attr0 = attributes[vertices[0]];\n        Vec<scalar, dim + 1> attr1 = attributes[vertices[1]];\n        Vec<scalar, dim + 1> attr2 = attributes[vertices[2]];\n\n        Vec<scalar, dim + 1> attr_inter = attr0 * barycentrics[0] +\n                                          attr1 * barycentrics[1] +\n                                          attr2 * barycentrics[2];\n\n        return attr_inter;\n    }\n};\n\n/// @brief A tetrahedron represented by indices of its vertices in a point set\nstruct IndexedTet {\n    uint32_t vertices[4];\n\n    RADFOAM_HD IndexedTet() {}\n\n    RADFOAM_HD IndexedTet(uint32_t i0, uint32_t i1, uint32_t i2, uint32_t i3) {\n        vertices[0] = i0;\n        vertices[1] = i1;\n        vertices[2] = i2;\n        vertices[3] = i3;\n    }\n\n    __device__ __forceinline__ uint32_t hash() const {\n        return mix(vertices[0]) ^ mix(vertices[1]) ^ mix(vertices[2]) ^\n               mix(vertices[3]);\n    }\n\n    RADFOAM_HD friend bool operator==(const IndexedTet &a,\n                                      const IndexedTet &b) {\n        return set_equal<4>(a.vertices, b.vertices);\n    }\n\n    RADFOAM_HD friend bool operator<(const IndexedTet &a, const IndexedTet &b) {\n        return set_less<4>(a.vertices, b.vertices);\n    }\n\n    RADFOAM_HD bool is_valid() {\n        return (vertices[0] < UINT32_MAX) && (vertices[1] < UINT32_MAX) &&\n               (vertices[2] < UINT32_MAX) && (vertices[3] < UINT32_MAX);\n    }\n\n    /// @brief Fetch the face of the tetrahedron opposite to a given vertex\n    /// @param i The index of the vertex opposite to the face\n    RADFOAM_HD IndexedTriangle face(uint32_t i) const {\n        switch (i % 4) {\n        case 0:\n            return IndexedTriangle(vertices[1], vertices[3], vertices[2]);\n        case 1:\n            return IndexedTriangle(vertices[0], vertices[2], vertices[3]);\n        case 2:\n            return IndexedTriangle(vertices[0], vertices[3], vertices[1]);\n        default:\n            return IndexedTriangle(vertices[0], vertices[1], vertices[2]);\n        }\n    }\n\n    /// @brief Compute the volume of the tetrahedron given the vertices\n    template <typename scalar>\n    RADFOAM_HD scalar volume(const Vec3<scalar> &v0,\n                             const Vec3<scalar> &v1,\n                             const Vec3<scalar> &v2,\n                             const Vec3<scalar> &v3) const {\n        return (v2 - v0).cross(v1 - v0).dot(v3 - v0) / 6;\n    }\n};\n\ninline RADFOAM_HD void\ntet_permutation(const IndexedTet &old, const IndexedTet &new_, int32_t *perm) {\n#pragma unroll\n    for (int i = 0; i < 4; i++) {\n        perm[i] = -1;\n#pragma unroll\n        for (int j = 0; j < 4; j++) {\n            if (new_.vertices[j] == old.vertices[i]) {\n                perm[i] = j;\n            }\n        }\n    }\n}\n\n/// @brief An edge represented by indices of its vertices in a point set\nstruct IndexedEdge {\n    uint32_t vertices[2];\n\n    RADFOAM_HD IndexedEdge() {}\n\n    RADFOAM_HD IndexedEdge(uint32_t i0, uint32_t i1) {\n        vertices[0] = i0;\n        vertices[1] = i1;\n    }\n\n    __device__ __forceinline__ uint32_t hash() const {\n        return mix(vertices[0]) ^ mix(vertices[1]);\n    }\n\n    RADFOAM_HD friend bool operator==(const IndexedEdge &a,\n                                      const IndexedEdge &b) {\n        return set_equal<2>(a.vertices, b.vertices);\n    }\n\n    RADFOAM_HD friend bool operator<(const IndexedEdge &a,\n                                     const IndexedEdge &b) {\n        return set_less<2>(a.vertices, b.vertices);\n    }\n\n    RADFOAM_HD bool is_valid() {\n        return (vertices[0] < UINT32_MAX) && (vertices[1] < UINT32_MAX);\n    }\n};\n\n} // namespace radfoam"
  },
  {
    "path": "src/utils/random.h",
    "content": "#pragma once\n\n#include <cmath>\n#include <limits>\n\n#include \"typing.h\"\n\nnamespace radfoam {\n\n// https://github.com/skeeto/hash-prospector\ninline RADFOAM_HD uint32_t mix(uint32_t x) {\n    x ^= x >> 17;\n    x *= 0xed5ad4bb;\n    x ^= x >> 11;\n    x *= 0xac4c1b51;\n    x ^= x >> 15;\n    x *= 0x31848bab;\n    x ^= x >> 14;\n    return x;\n}\n\nstruct RNGState {\n    uint32_t bits;\n};\n\n/// @brief Create a new RNG state with the given seed\ninline RADFOAM_HD RNGState make_rng(uint32_t seed) {\n    return RNGState{mix(seed ^ 0x2815db5b)};\n}\n\n#ifdef __CUDACC__\n/// @brief Create an RNG with state unique to the current thread\ninline __device__ RNGState thread_rng() {\n    uint32_t seed =\n        threadIdx.x + blockDim.x * (threadIdx.y + blockDim.y * threadIdx.z) +\n        blockDim.x * blockDim.y * blockDim.z *\n            (blockIdx.x + gridDim.x * (blockIdx.y + gridDim.y * blockIdx.z));\n    return make_rng(seed);\n}\n#endif\n\n/// @brief Generate a random integer in the range [0, 0xffffffff]\ninline RADFOAM_HD uint32_t randint(RNGState &rngstate) {\n    uint32_t x = rngstate.bits;\n    rngstate.bits = mix(rngstate.bits + 1);\n    return x;\n}\n\n/// @brief Generate a random integer in the range [min, max)\ninline RADFOAM_HD uint32_t randint(RNGState &rngstate,\n                                   uint32_t min,\n                                   uint32_t max) {\n    uint32_t diff = max - min;\n    uint32_t x = randint(rngstate);\n    x /= (0xffffffff / diff);\n    return std::min(x, diff - 1) + min;\n}\n\n/// @brief Generate a random float in the range [0, 1]\ninline RADFOAM_HD float rand(RNGState &rngstate) {\n    return float(randint(rngstate)) / float(0xffffffff);\n}\n\n/// @brief Generate a random float from a unit normal distribution\ninline RADFOAM_HD float randn(RNGState &rngstate) {\n    // sample normal distribution using Box - Muller transform\n    float u1 = std::max(rand(rngstate), std::numeric_limits<float>::min());\n    float u2 = rand(rngstate);\n#ifdef __CUDA_ARCH__\n    float result = sqrtf(-2 * logf(u1)) * cosf(2 * M_PIf * u2);\n#else\n    float result = std::sqrt(-2 * std::log(u1)) * std::cos(2 * M_PIf * u2);\n#endif\n    return float(result);\n}\n\n} // namespace radfoam"
  },
  {
    "path": "src/utils/typing.h",
    "content": "#pragma once\n\n#include <string>\n\n#include <cuda_fp16.h>\n\n#ifdef __CUDACC__\n#define RADFOAM_HD __host__ __device__\n#else\n#define RADFOAM_HD\n#endif\n\n#ifndef M_PI\n#define M_PI 3.14159265358979323846\n#endif\n\n#ifndef M_PIf\n#define M_PIf 3.14159265358979323846f\n#endif\n\nnamespace radfoam {\n\nenum ScalarType {\n    Float16,\n    Float32,\n    Float64,\n    UInt32,\n    Int32,\n    Int64,\n};\n\ninline std::string scalar_to_string(ScalarType type) {\n    switch (type) {\n    case Float16:\n        return \"float16\";\n    case Float32:\n        return \"float32\";\n    case Float64:\n        return \"float64\";\n    case UInt32:\n        return \"uint32\";\n    case Int32:\n        return \"int32\";\n    case Int64:\n        return \"int64\";\n    default:\n        return \"unknown\";\n    }\n}\n\ninline size_t scalar_size(ScalarType type) {\n    switch (type) {\n    case Float16:\n        return 2;\n    case Float32:\n        return 4;\n    case Float64:\n        return 8;\n    case UInt32:\n        return 4;\n    case Int32:\n        return 4;\n    case Int64:\n        return 8;\n    default:\n        return 0;\n    }\n}\n\ntemplate <typename T>\nconstexpr ScalarType scalar_code() = delete;\n\ntemplate <>\nconstexpr ScalarType scalar_code<__half>() {\n    return Float16;\n}\n\ntemplate <>\nconstexpr ScalarType scalar_code<float>() {\n    return Float32;\n}\n\ntemplate <>\nconstexpr ScalarType scalar_code<double>() {\n    return Float64;\n}\n\ntemplate <>\nconstexpr ScalarType scalar_code<uint32_t>() {\n    return UInt32;\n}\n\ntemplate <>\nconstexpr ScalarType scalar_code<int32_t>() {\n    return Int32;\n}\n\ntemplate <>\nconstexpr ScalarType scalar_code<int64_t>() {\n    return Int64;\n}\n\ntemplate <typename T>\nconstexpr const char *scalar_cxx_name() = delete;\n\ntemplate <>\nconstexpr const char *scalar_cxx_name<uint32_t>() {\n    return \"uint32_t\";\n}\n\ntemplate <>\nconstexpr const char *scalar_cxx_name<__half>() {\n    return \"__half\";\n}\n\ntemplate <>\nconstexpr const char *scalar_cxx_name<float>() {\n    return \"float\";\n}\n\ntemplate <>\nconstexpr const char *scalar_cxx_name<double>() {\n    return \"double\";\n}\n\ntemplate <>\nconstexpr const char *scalar_cxx_name<int32_t>() {\n    return \"int32_t\";\n}\n\ntemplate <>\nconstexpr const char *scalar_cxx_name<int64_t>() {\n    return \"int64_t\";\n}\n\nenum ColorMap {\n    Gray = 0,\n    Viridis = 1,\n    Inferno = 2,\n    Turbo = 3,\n};\n\nstruct CMapTable {\n    const float *const *data;\n    const int *sizes;\n};\n\ntemplate <typename T>\nRADFOAM_HD void swap(T &a, T &b) {\n    typename std::decay<T>::type tmp = a;\n    a = b;\n    b = tmp;\n}\n\n/// @brief Compute the base-2 logarithm of an integer\ninline RADFOAM_HD uint32_t log2(uint32_t x) {\n#if defined(__CUDA_ARCH__)\n    return (x > 0) ? 31 - __clz(x) : 0;\n#else\n    uint32_t result = 0;\n    while (x >>= 1) {\n        result++;\n    }\n    return result;\n#endif\n}\n\n/// @brief Compute the smallest power of 2 greater than or equal to x\ninline RADFOAM_HD uint32_t pow2_round_up(uint32_t x) {\n    return (x > 1) ? 1 << (log2(x - 1) + 1) : 1;\n}\n\n} // namespace radfoam"
  },
  {
    "path": "src/utils/unenumerate_iterator.cuh",
    "content": "#pragma once\n\n#include <cub/iterator/arg_index_input_iterator.cuh>\n\nnamespace radfoam {\n\n/// @brief An output iterator that removes the key from a key-value pair\ntemplate <typename T>\nstruct UnenumerateIterator {\n    using value_type = void;\n    using reference = void;\n    using pointer = void;\n    using difference_type = ptrdiff_t;\n    using iterator_category = std::output_iterator_tag;\n\n    T *ptr;\n\n    __host__ __device__ __forceinline__ UnenumerateIterator() : ptr(nullptr) {}\n\n    __host__ __device__ __forceinline__ UnenumerateIterator(T *ptr)\n        : ptr(ptr) {}\n\n    __host__ __device__ __forceinline__ UnenumerateIterator operator++() {\n        return UnenumerateIterator(ptr + 1);\n    }\n\n    __host__ __device__ __forceinline__ UnenumerateIterator operator++(int) {\n        UnenumerateIterator retval = *this;\n        ptr++;\n        return retval;\n    }\n\n    __host__ __device__ __forceinline__ UnenumerateIterator &operator*() {\n        return *this;\n    }\n\n    template <typename Distance>\n    __host__ __device__ __forceinline__ UnenumerateIterator\n    operator+(Distance n) const {\n        return UnenumerateIterator(ptr + n);\n    }\n\n    template <typename Distance>\n    __host__ __device__ __forceinline__ UnenumerateIterator &\n    operator+=(Distance n) {\n        ptr += n;\n        return *this;\n    }\n\n    template <typename Distance>\n    __host__ __device__ __forceinline__ UnenumerateIterator\n    operator-(Distance n) const {\n        return UnenumerateIterator(ptr - n);\n    }\n\n    template <typename Distance>\n    __host__ __device__ __forceinline__ UnenumerateIterator &\n    operator-=(Distance n) {\n        ptr -= n;\n        return *this;\n    }\n\n    __host__ __device__ __forceinline__ ptrdiff_t\n    operator-(UnenumerateIterator other) const {\n        return ptr - other.ptr;\n    }\n\n    template <typename Distance>\n    __host__ __device__ __forceinline__ UnenumerateIterator\n    operator[](Distance n) {\n        return UnenumerateIterator(ptr + n);\n    }\n\n    __host__ __device__ __forceinline__ void\n    operator=(const cub::KeyValuePair<ptrdiff_t, T> &x) {\n        *ptr = x.value;\n    }\n};\n\n} // namespace radfoam\n"
  },
  {
    "path": "src/viewer/viewer.cpp",
    "content": "#include <atomic>\n#include <chrono>\n#include <condition_variable>\n#include <iostream>\n#include <mutex>\n#include <stdexcept>\n#include <thread>\n\n#include <GL/gl3w.h>\n#include <GLFW/glfw3.h>\n#include <cudaGL.h>\n\n#include \"imgui.h\"\n#include \"imgui_impl_glfw.h\"\n#include \"imgui_impl_opengl3.h\"\n\n#include \"../aabb_tree/aabb_tree.h\"\n#include \"../utils/cuda_array.h\"\n#include \"../utils/cuda_helpers.h\"\n#include \"viewer.h\"\n\nvoid glfwErrorCallback(int error, const char *description) {\n    std::cerr << \"GLFW Error (\" << error << \"): \" << description << std::endl;\n}\n\nnamespace radfoam {\n\nnamespace {\n\nbool gl3w_initialized = false;\n\nconst char *vertex_shader_source = R\"(#version 330 core\nout vec2 tex_coords;\n\nvoid main() {\n    vec2 pos = vec2((gl_VertexID & 1) * 2.0 - 1.0, (gl_VertexID & 2) - 1.0);\n    tex_coords = pos * 0.5 + 0.5;\n    gl_Position = vec4(pos, 0.0, 1.0);\n}\n)\";\n\nconst char *fragment_shader_source = R\"(#version 330 core\nin vec2 tex_coords;\nout vec4 frag_color;\n\nuniform sampler2D frame;\n\nvoid main() {\n    frag_color = texture(frame, tex_coords);\n}\n)\";\n\nvoid gl_debug_callback(GLenum source,\n                       GLenum type,\n                       GLuint id,\n                       GLenum severity,\n                       GLsizei length,\n                       const GLchar *message,\n                       const void *user_param) {\n    if (severity == GL_DEBUG_SEVERITY_NOTIFICATION)\n        return;\n    std::cerr << \"OpenGL: \" << message << std::endl;\n}\n\nGLuint create_program() {\n    GLuint vertex_shader = gl_check(glCreateShader(GL_VERTEX_SHADER));\n    gl_check(glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL));\n    gl_check(glCompileShader(vertex_shader));\n\n    GLint success;\n    glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);\n    if (!success) {\n        char info_log[512];\n        glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);\n        throw std::runtime_error(\"vertex shader compilation failed: \" +\n                                 std::string(info_log));\n    }\n\n    GLuint fragment_shader = gl_check(glCreateShader(GL_FRAGMENT_SHADER));\n    gl_check(glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL));\n    gl_check(glCompileShader(fragment_shader));\n\n    glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);\n    if (!success) {\n        char info_log[512];\n        glGetShaderInfoLog(fragment_shader, 512, NULL, info_log);\n        throw std::runtime_error(\"fragment shader compilation failed: \" +\n                                 std::string(info_log));\n    }\n\n    GLuint program = gl_check(glCreateProgram());\n    gl_check(glAttachShader(program, vertex_shader));\n    gl_check(glAttachShader(program, fragment_shader));\n    gl_check(glLinkProgram(program));\n\n    glGetProgramiv(program, GL_LINK_STATUS, &success);\n    if (!success) {\n        char info_log[512];\n        glGetProgramInfoLog(program, 512, NULL, info_log);\n        throw std::runtime_error(\"program linking failed: \" +\n                                 std::string(info_log));\n    }\n\n    gl_check(glDeleteShader(vertex_shader));\n    gl_check(glDeleteShader(fragment_shader));\n\n    return program;\n}\n\nGLuint allocate_texture(int width, int height) {\n    GLuint texture;\n    gl_check(glGenTextures(1, &texture));\n    gl_check(glBindTexture(GL_TEXTURE_2D, texture));\n    gl_check(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));\n    gl_check(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));\n    gl_check(\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));\n    gl_check(\n        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));\n    gl_check(glTexImage2D(GL_TEXTURE_2D,\n                          0,\n                          GL_RGBA8,\n                          width,\n                          height,\n                          0,\n                          GL_RGBA,\n                          GL_UNSIGNED_BYTE,\n                          nullptr));\n    gl_check(glBindTexture(GL_TEXTURE_2D, 0));\n    return texture;\n}\n\nCUgraphicsResource register_texture(GLuint texture) {\n    CUgraphicsResource resource;\n    cuda_check(\n        cuGraphicsGLRegisterImage(&resource,\n                                  texture,\n                                  GL_TEXTURE_2D,\n                                  CU_GRAPHICS_REGISTER_FLAGS_WRITE_DISCARD));\n    return resource;\n}\n\nconstexpr size_t NUM_CMAPS = 4;\n\nconst float gray_data[] = {0.0, 0.0, 0.0, 1.0, 1.0, 1.0};\n\nconst float viridis_data[] = {\n    0.267004, 0.004874, 0.329415, 0.268510, 0.009605, 0.335427, 0.269944,\n    0.014625, 0.341379, 0.271305, 0.019942, 0.347269, 0.272594, 0.025563,\n    0.353093, 0.273809, 0.031497, 0.358853, 0.274952, 0.037752, 0.364543,\n    0.276022, 0.044167, 0.370164, 0.277018, 0.050344, 0.375715, 0.277941,\n    0.056324, 0.381191, 0.278791, 0.062145, 0.386592, 0.279566, 0.067836,\n    0.391917, 0.280267, 0.073417, 0.397163, 0.280894, 0.078907, 0.402329,\n    0.281446, 0.084320, 0.407414, 0.281924, 0.089666, 0.412415, 0.282327,\n    0.094955, 0.417331, 0.282656, 0.100196, 0.422160, 0.282910, 0.105393,\n    0.426902, 0.283091, 0.110553, 0.431554, 0.283197, 0.115680, 0.436115,\n    0.283229, 0.120777, 0.440584, 0.283187, 0.125848, 0.444960, 0.283072,\n    0.130895, 0.449241, 0.282884, 0.135920, 0.453427, 0.282623, 0.140926,\n    0.457517, 0.282290, 0.145912, 0.461510, 0.281887, 0.150881, 0.465405,\n    0.281412, 0.155834, 0.469201, 0.280868, 0.160771, 0.472899, 0.280255,\n    0.165693, 0.476498, 0.279574, 0.170599, 0.479997, 0.278826, 0.175490,\n    0.483397, 0.278012, 0.180367, 0.486697, 0.277134, 0.185228, 0.489898,\n    0.276194, 0.190074, 0.493001, 0.275191, 0.194905, 0.496005, 0.274128,\n    0.199721, 0.498911, 0.273006, 0.204520, 0.501721, 0.271828, 0.209303,\n    0.504434, 0.270595, 0.214069, 0.507052, 0.269308, 0.218818, 0.509577,\n    0.267968, 0.223549, 0.512008, 0.266580, 0.228262, 0.514349, 0.265145,\n    0.232956, 0.516599, 0.263663, 0.237631, 0.518762, 0.262138, 0.242286,\n    0.520837, 0.260571, 0.246922, 0.522828, 0.258965, 0.251537, 0.524736,\n    0.257322, 0.256130, 0.526563, 0.255645, 0.260703, 0.528312, 0.253935,\n    0.265254, 0.529983, 0.252194, 0.269783, 0.531579, 0.250425, 0.274290,\n    0.533103, 0.248629, 0.278775, 0.534556, 0.246811, 0.283237, 0.535941,\n    0.244972, 0.287675, 0.537260, 0.243113, 0.292092, 0.538516, 0.241237,\n    0.296485, 0.539709, 0.239346, 0.300855, 0.540844, 0.237441, 0.305202,\n    0.541921, 0.235526, 0.309527, 0.542944, 0.233603, 0.313828, 0.543914,\n    0.231674, 0.318106, 0.544834, 0.229739, 0.322361, 0.545706, 0.227802,\n    0.326594, 0.546532, 0.225863, 0.330805, 0.547314, 0.223925, 0.334994,\n    0.548053, 0.221989, 0.339161, 0.548752, 0.220057, 0.343307, 0.549413,\n    0.218130, 0.347432, 0.550038, 0.216210, 0.351535, 0.550627, 0.214298,\n    0.355619, 0.551184, 0.212395, 0.359683, 0.551710, 0.210503, 0.363727,\n    0.552206, 0.208623, 0.367752, 0.552675, 0.206756, 0.371758, 0.553117,\n    0.204903, 0.375746, 0.553533, 0.203063, 0.379716, 0.553925, 0.201239,\n    0.383670, 0.554294, 0.199430, 0.387607, 0.554642, 0.197636, 0.391528,\n    0.554969, 0.195860, 0.395433, 0.555276, 0.194100, 0.399323, 0.555565,\n    0.192357, 0.403199, 0.555836, 0.190631, 0.407061, 0.556089, 0.188923,\n    0.410910, 0.556326, 0.187231, 0.414746, 0.556547, 0.185556, 0.418570,\n    0.556753, 0.183898, 0.422383, 0.556944, 0.182256, 0.426184, 0.557120,\n    0.180629, 0.429975, 0.557282, 0.179019, 0.433756, 0.557430, 0.177423,\n    0.437527, 0.557565, 0.175841, 0.441290, 0.557685, 0.174274, 0.445044,\n    0.557792, 0.172719, 0.448791, 0.557885, 0.171176, 0.452530, 0.557965,\n    0.169646, 0.456262, 0.558030, 0.168126, 0.459988, 0.558082, 0.166617,\n    0.463708, 0.558119, 0.165117, 0.467423, 0.558141, 0.163625, 0.471133,\n    0.558148, 0.162142, 0.474838, 0.558140, 0.160665, 0.478540, 0.558115,\n    0.159194, 0.482237, 0.558073, 0.157729, 0.485932, 0.558013, 0.156270,\n    0.489624, 0.557936, 0.154815, 0.493313, 0.557840, 0.153364, 0.497000,\n    0.557724, 0.151918, 0.500685, 0.557587, 0.150476, 0.504369, 0.557430,\n    0.149039, 0.508051, 0.557250, 0.147607, 0.511733, 0.557049, 0.146180,\n    0.515413, 0.556823, 0.144759, 0.519093, 0.556572, 0.143343, 0.522773,\n    0.556295, 0.141935, 0.526453, 0.555991, 0.140536, 0.530132, 0.555659,\n    0.139147, 0.533812, 0.555298, 0.137770, 0.537492, 0.554906, 0.136408,\n    0.541173, 0.554483, 0.135066, 0.544853, 0.554029, 0.133743, 0.548535,\n    0.553541, 0.132444, 0.552216, 0.553018, 0.131172, 0.555899, 0.552459,\n    0.129933, 0.559582, 0.551864, 0.128729, 0.563265, 0.551229, 0.127568,\n    0.566949, 0.550556, 0.126453, 0.570633, 0.549841, 0.125394, 0.574318,\n    0.549086, 0.124395, 0.578002, 0.548287, 0.123463, 0.581687, 0.547445,\n    0.122606, 0.585371, 0.546557, 0.121831, 0.589055, 0.545623, 0.121148,\n    0.592739, 0.544641, 0.120565, 0.596422, 0.543611, 0.120092, 0.600104,\n    0.542530, 0.119738, 0.603785, 0.541400, 0.119512, 0.607464, 0.540218,\n    0.119423, 0.611141, 0.538982, 0.119483, 0.614817, 0.537692, 0.119699,\n    0.618490, 0.536347, 0.120081, 0.622161, 0.534946, 0.120638, 0.625828,\n    0.533488, 0.121380, 0.629492, 0.531973, 0.122312, 0.633153, 0.530398,\n    0.123444, 0.636809, 0.528763, 0.124780, 0.640461, 0.527068, 0.126326,\n    0.644107, 0.525311, 0.128087, 0.647749, 0.523491, 0.130067, 0.651384,\n    0.521608, 0.132268, 0.655014, 0.519661, 0.134692, 0.658636, 0.517649,\n    0.137339, 0.662252, 0.515571, 0.140210, 0.665859, 0.513427, 0.143303,\n    0.669459, 0.511215, 0.146616, 0.673050, 0.508936, 0.150148, 0.676631,\n    0.506589, 0.153894, 0.680203, 0.504172, 0.157851, 0.683765, 0.501686,\n    0.162016, 0.687316, 0.499129, 0.166383, 0.690856, 0.496502, 0.170948,\n    0.694384, 0.493803, 0.175707, 0.697900, 0.491033, 0.180653, 0.701402,\n    0.488189, 0.185783, 0.704891, 0.485273, 0.191090, 0.708366, 0.482284,\n    0.196571, 0.711827, 0.479221, 0.202219, 0.715272, 0.476084, 0.208030,\n    0.718701, 0.472873, 0.214000, 0.722114, 0.469588, 0.220124, 0.725509,\n    0.466226, 0.226397, 0.728888, 0.462789, 0.232815, 0.732247, 0.459277,\n    0.239374, 0.735588, 0.455688, 0.246070, 0.738910, 0.452024, 0.252899,\n    0.742211, 0.448284, 0.259857, 0.745492, 0.444467, 0.266941, 0.748751,\n    0.440573, 0.274149, 0.751988, 0.436601, 0.281477, 0.755203, 0.432552,\n    0.288921, 0.758394, 0.428426, 0.296479, 0.761561, 0.424223, 0.304148,\n    0.764704, 0.419943, 0.311925, 0.767822, 0.415586, 0.319809, 0.770914,\n    0.411152, 0.327796, 0.773980, 0.406640, 0.335885, 0.777018, 0.402049,\n    0.344074, 0.780029, 0.397381, 0.352360, 0.783011, 0.392636, 0.360741,\n    0.785964, 0.387814, 0.369214, 0.788888, 0.382914, 0.377779, 0.791781,\n    0.377939, 0.386433, 0.794644, 0.372886, 0.395174, 0.797475, 0.367757,\n    0.404001, 0.800275, 0.362552, 0.412913, 0.803041, 0.357269, 0.421908,\n    0.805774, 0.351910, 0.430983, 0.808473, 0.346476, 0.440137, 0.811138,\n    0.340967, 0.449368, 0.813768, 0.335384, 0.458674, 0.816363, 0.329727,\n    0.468053, 0.818921, 0.323998, 0.477504, 0.821444, 0.318195, 0.487026,\n    0.823929, 0.312321, 0.496615, 0.826376, 0.306377, 0.506271, 0.828786,\n    0.300362, 0.515992, 0.831158, 0.294279, 0.525776, 0.833491, 0.288127,\n    0.535621, 0.835785, 0.281908, 0.545524, 0.838039, 0.275626, 0.555484,\n    0.840254, 0.269281, 0.565498, 0.842430, 0.262877, 0.575563, 0.844566,\n    0.256415, 0.585678, 0.846661, 0.249897, 0.595839, 0.848717, 0.243329,\n    0.606045, 0.850733, 0.236712, 0.616293, 0.852709, 0.230052, 0.626579,\n    0.854645, 0.223353, 0.636902, 0.856542, 0.216620, 0.647257, 0.858400,\n    0.209861, 0.657642, 0.860219, 0.203082, 0.668054, 0.861999, 0.196293,\n    0.678489, 0.863742, 0.189503, 0.688944, 0.865448, 0.182725, 0.699415,\n    0.867117, 0.175971, 0.709898, 0.868751, 0.169257, 0.720391, 0.870350,\n    0.162603, 0.730889, 0.871916, 0.156029, 0.741388, 0.873449, 0.149561,\n    0.751884, 0.874951, 0.143228, 0.762373, 0.876424, 0.137064, 0.772852,\n    0.877868, 0.131109, 0.783315, 0.879285, 0.125405, 0.793760, 0.880678,\n    0.120005, 0.804182, 0.882046, 0.114965, 0.814576, 0.883393, 0.110347,\n    0.824940, 0.884720, 0.106217, 0.835270, 0.886029, 0.102646, 0.845561,\n    0.887322, 0.099702, 0.855810, 0.888601, 0.097452, 0.866013, 0.889868,\n    0.095953, 0.876168, 0.891125, 0.095250, 0.886271, 0.892374, 0.095374,\n    0.896320, 0.893616, 0.096335, 0.906311, 0.894855, 0.098125, 0.916242,\n    0.896091, 0.100717, 0.926106, 0.897330, 0.104071, 0.935904, 0.898570,\n    0.108131, 0.945636, 0.899815, 0.112838, 0.955300, 0.901065, 0.118128,\n    0.964894, 0.902323, 0.123941, 0.974417, 0.903590, 0.130215, 0.983868,\n    0.904867, 0.136897, 0.993248, 0.906157, 0.143936};\n\nconst float inferno_data[] = {\n    0.001462, 0.000466, 0.013866, 0.002267, 0.001270, 0.018570, 0.003299,\n    0.002249, 0.024239, 0.004547, 0.003392, 0.030909, 0.006006, 0.004692,\n    0.038558, 0.007676, 0.006136, 0.046836, 0.009561, 0.007713, 0.055143,\n    0.011663, 0.009417, 0.063460, 0.013995, 0.011225, 0.071862, 0.016561,\n    0.013136, 0.080282, 0.019373, 0.015133, 0.088767, 0.022447, 0.017199,\n    0.097327, 0.025793, 0.019331, 0.105930, 0.029432, 0.021503, 0.114621,\n    0.033385, 0.023702, 0.123397, 0.037668, 0.025921, 0.132232, 0.042253,\n    0.028139, 0.141141, 0.046915, 0.030324, 0.150164, 0.051644, 0.032474,\n    0.159254, 0.056449, 0.034569, 0.168414, 0.061340, 0.036590, 0.177642,\n    0.066331, 0.038504, 0.186962, 0.071429, 0.040294, 0.196354, 0.076637,\n    0.041905, 0.205799, 0.081962, 0.043328, 0.215289, 0.087411, 0.044556,\n    0.224813, 0.092990, 0.045583, 0.234358, 0.098702, 0.046402, 0.243904,\n    0.104551, 0.047008, 0.253430, 0.110536, 0.047399, 0.262912, 0.116656,\n    0.047574, 0.272321, 0.122908, 0.047536, 0.281624, 0.129285, 0.047293,\n    0.290788, 0.135778, 0.046856, 0.299776, 0.142378, 0.046242, 0.308553,\n    0.149073, 0.045468, 0.317085, 0.155850, 0.044559, 0.325338, 0.162689,\n    0.043554, 0.333277, 0.169575, 0.042489, 0.340874, 0.176493, 0.041402,\n    0.348111, 0.183429, 0.040329, 0.354971, 0.190367, 0.039309, 0.361447,\n    0.197297, 0.038400, 0.367535, 0.204209, 0.037632, 0.373238, 0.211095,\n    0.037030, 0.378563, 0.217949, 0.036615, 0.383522, 0.224763, 0.036405,\n    0.388129, 0.231538, 0.036405, 0.392400, 0.238273, 0.036621, 0.396353,\n    0.244967, 0.037055, 0.400007, 0.251620, 0.037705, 0.403378, 0.258234,\n    0.038571, 0.406485, 0.264810, 0.039647, 0.409345, 0.271347, 0.040922,\n    0.411976, 0.277850, 0.042353, 0.414392, 0.284321, 0.043933, 0.416608,\n    0.290763, 0.045644, 0.418637, 0.297178, 0.047470, 0.420491, 0.303568,\n    0.049396, 0.422182, 0.309935, 0.051407, 0.423721, 0.316282, 0.053490,\n    0.425116, 0.322610, 0.055634, 0.426377, 0.328921, 0.057827, 0.427511,\n    0.335217, 0.060060, 0.428524, 0.341500, 0.062325, 0.429425, 0.347771,\n    0.064616, 0.430217, 0.354032, 0.066925, 0.430906, 0.360284, 0.069247,\n    0.431497, 0.366529, 0.071579, 0.431994, 0.372768, 0.073915, 0.432400,\n    0.379001, 0.076253, 0.432719, 0.385228, 0.078591, 0.432955, 0.391453,\n    0.080927, 0.433109, 0.397674, 0.083257, 0.433183, 0.403894, 0.085580,\n    0.433179, 0.410113, 0.087896, 0.433098, 0.416331, 0.090203, 0.432943,\n    0.422549, 0.092501, 0.432714, 0.428768, 0.094790, 0.432412, 0.434987,\n    0.097069, 0.432039, 0.441207, 0.099338, 0.431594, 0.447428, 0.101597,\n    0.431080, 0.453651, 0.103848, 0.430498, 0.459875, 0.106089, 0.429846,\n    0.466100, 0.108322, 0.429125, 0.472328, 0.110547, 0.428334, 0.478558,\n    0.112764, 0.427475, 0.484789, 0.114974, 0.426548, 0.491022, 0.117179,\n    0.425552, 0.497257, 0.119379, 0.424488, 0.503493, 0.121575, 0.423356,\n    0.509730, 0.123769, 0.422156, 0.515967, 0.125960, 0.420887, 0.522206,\n    0.128150, 0.419549, 0.528444, 0.130341, 0.418142, 0.534683, 0.132534,\n    0.416667, 0.540920, 0.134729, 0.415123, 0.547157, 0.136929, 0.413511,\n    0.553392, 0.139134, 0.411829, 0.559624, 0.141346, 0.410078, 0.565854,\n    0.143567, 0.408258, 0.572081, 0.145797, 0.406369, 0.578304, 0.148039,\n    0.404411, 0.584521, 0.150294, 0.402385, 0.590734, 0.152563, 0.400290,\n    0.596940, 0.154848, 0.398125, 0.603139, 0.157151, 0.395891, 0.609330,\n    0.159474, 0.393589, 0.615513, 0.161817, 0.391219, 0.621685, 0.164184,\n    0.388781, 0.627847, 0.166575, 0.386276, 0.633998, 0.168992, 0.383704,\n    0.640135, 0.171438, 0.381065, 0.646260, 0.173914, 0.378359, 0.652369,\n    0.176421, 0.375586, 0.658463, 0.178962, 0.372748, 0.664540, 0.181539,\n    0.369846, 0.670599, 0.184153, 0.366879, 0.676638, 0.186807, 0.363849,\n    0.682656, 0.189501, 0.360757, 0.688653, 0.192239, 0.357603, 0.694627,\n    0.195021, 0.354388, 0.700576, 0.197851, 0.351113, 0.706500, 0.200728,\n    0.347777, 0.712396, 0.203656, 0.344383, 0.718264, 0.206636, 0.340931,\n    0.724103, 0.209670, 0.337424, 0.729909, 0.212759, 0.333861, 0.735683,\n    0.215906, 0.330245, 0.741423, 0.219112, 0.326576, 0.747127, 0.222378,\n    0.322856, 0.752794, 0.225706, 0.319085, 0.758422, 0.229097, 0.315266,\n    0.764010, 0.232554, 0.311399, 0.769556, 0.236077, 0.307485, 0.775059,\n    0.239667, 0.303526, 0.780517, 0.243327, 0.299523, 0.785929, 0.247056,\n    0.295477, 0.791293, 0.250856, 0.291390, 0.796607, 0.254728, 0.287264,\n    0.801871, 0.258674, 0.283099, 0.807082, 0.262692, 0.278898, 0.812239,\n    0.266786, 0.274661, 0.817341, 0.270954, 0.270390, 0.822386, 0.275197,\n    0.266085, 0.827372, 0.279517, 0.261750, 0.832299, 0.283913, 0.257383,\n    0.837165, 0.288385, 0.252988, 0.841969, 0.292933, 0.248564, 0.846709,\n    0.297559, 0.244113, 0.851384, 0.302260, 0.239636, 0.855992, 0.307038,\n    0.235133, 0.860533, 0.311892, 0.230606, 0.865006, 0.316822, 0.226055,\n    0.869409, 0.321827, 0.221482, 0.873741, 0.326906, 0.216886, 0.878001,\n    0.332060, 0.212268, 0.882188, 0.337287, 0.207628, 0.886302, 0.342586,\n    0.202968, 0.890341, 0.347957, 0.198286, 0.894305, 0.353399, 0.193584,\n    0.898192, 0.358911, 0.188860, 0.902003, 0.364492, 0.184116, 0.905735,\n    0.370140, 0.179350, 0.909390, 0.375856, 0.174563, 0.912966, 0.381636,\n    0.169755, 0.916462, 0.387481, 0.164924, 0.919879, 0.393389, 0.160070,\n    0.923215, 0.399359, 0.155193, 0.926470, 0.405389, 0.150292, 0.929644,\n    0.411479, 0.145367, 0.932737, 0.417627, 0.140417, 0.935747, 0.423831,\n    0.135440, 0.938675, 0.430091, 0.130438, 0.941521, 0.436405, 0.125409,\n    0.944285, 0.442772, 0.120354, 0.946965, 0.449191, 0.115272, 0.949562,\n    0.455660, 0.110164, 0.952075, 0.462178, 0.105031, 0.954506, 0.468744,\n    0.099874, 0.956852, 0.475356, 0.094695, 0.959114, 0.482014, 0.089499,\n    0.961293, 0.488716, 0.084289, 0.963387, 0.495462, 0.079073, 0.965397,\n    0.502249, 0.073859, 0.967322, 0.509078, 0.068659, 0.969163, 0.515946,\n    0.063488, 0.970919, 0.522853, 0.058367, 0.972590, 0.529798, 0.053324,\n    0.974176, 0.536780, 0.048392, 0.975677, 0.543798, 0.043618, 0.977092,\n    0.550850, 0.039050, 0.978422, 0.557937, 0.034931, 0.979666, 0.565057,\n    0.031409, 0.980824, 0.572209, 0.028508, 0.981895, 0.579392, 0.026250,\n    0.982881, 0.586606, 0.024661, 0.983779, 0.593849, 0.023770, 0.984591,\n    0.601122, 0.023606, 0.985315, 0.608422, 0.024202, 0.985952, 0.615750,\n    0.025592, 0.986502, 0.623105, 0.027814, 0.986964, 0.630485, 0.030908,\n    0.987337, 0.637890, 0.034916, 0.987622, 0.645320, 0.039886, 0.987819,\n    0.652773, 0.045581, 0.987926, 0.660250, 0.051750, 0.987945, 0.667748,\n    0.058329, 0.987874, 0.675267, 0.065257, 0.987714, 0.682807, 0.072489,\n    0.987464, 0.690366, 0.079990, 0.987124, 0.697944, 0.087731, 0.986694,\n    0.705540, 0.095694, 0.986175, 0.713153, 0.103863, 0.985566, 0.720782,\n    0.112229, 0.984865, 0.728427, 0.120785, 0.984075, 0.736087, 0.129527,\n    0.983196, 0.743758, 0.138453, 0.982228, 0.751442, 0.147565, 0.981173,\n    0.759135, 0.156863, 0.980032, 0.766837, 0.166353, 0.978806, 0.774545,\n    0.176037, 0.977497, 0.782258, 0.185923, 0.976108, 0.789974, 0.196018,\n    0.974638, 0.797692, 0.206332, 0.973088, 0.805409, 0.216877, 0.971468,\n    0.813122, 0.227658, 0.969783, 0.820825, 0.238686, 0.968041, 0.828515,\n    0.249972, 0.966243, 0.836191, 0.261534, 0.964394, 0.843848, 0.273391,\n    0.962517, 0.851476, 0.285546, 0.960626, 0.859069, 0.298010, 0.958720,\n    0.866624, 0.310820, 0.956834, 0.874129, 0.323974, 0.954997, 0.881569,\n    0.337475, 0.953215, 0.888942, 0.351369, 0.951546, 0.896226, 0.365627,\n    0.950018, 0.903409, 0.380271, 0.948683, 0.910473, 0.395289, 0.947594,\n    0.917399, 0.410665, 0.946809, 0.924168, 0.426373, 0.946392, 0.930761,\n    0.442367, 0.946403, 0.937159, 0.458592, 0.946903, 0.943348, 0.474970,\n    0.947937, 0.949318, 0.491426, 0.949545, 0.955063, 0.507860, 0.951740,\n    0.960587, 0.524203, 0.954529, 0.965896, 0.540361, 0.957896, 0.971003,\n    0.556275, 0.961812, 0.975924, 0.571925, 0.966249, 0.980678, 0.587206,\n    0.971162, 0.985282, 0.602154, 0.976511, 0.989753, 0.616760, 0.982257,\n    0.994109, 0.631017, 0.988362, 0.998364, 0.644924};\n\nconst float turbo_data[] = {\n    0.18995, 0.07176, 0.23217, 0.19483, 0.08339, 0.26149, 0.19956, 0.09498,\n    0.29024, 0.20415, 0.10652, 0.31844, 0.20860, 0.11802, 0.34607, 0.21291,\n    0.12947, 0.37314, 0.21708, 0.14087, 0.39964, 0.22111, 0.15223, 0.42558,\n    0.22500, 0.16354, 0.45096, 0.22875, 0.17481, 0.47578, 0.23236, 0.18603,\n    0.50004, 0.23582, 0.19720, 0.52373, 0.23915, 0.20833, 0.54686, 0.24234,\n    0.21941, 0.56942, 0.24539, 0.23044, 0.59142, 0.24830, 0.24143, 0.61286,\n    0.25107, 0.25237, 0.63374, 0.25369, 0.26327, 0.65406, 0.25618, 0.27412,\n    0.67381, 0.25853, 0.28492, 0.69300, 0.26074, 0.29568, 0.71162, 0.26280,\n    0.30639, 0.72968, 0.26473, 0.31706, 0.74718, 0.26652, 0.32768, 0.76412,\n    0.26816, 0.33825, 0.78050, 0.26967, 0.34878, 0.79631, 0.27103, 0.35926,\n    0.81156, 0.27226, 0.36970, 0.82624, 0.27334, 0.38008, 0.84037, 0.27429,\n    0.39043, 0.85393, 0.27509, 0.40072, 0.86692, 0.27576, 0.41097, 0.87936,\n    0.27628, 0.42118, 0.89123, 0.27667, 0.43134, 0.90254, 0.27691, 0.44145,\n    0.91328, 0.27701, 0.45152, 0.92347, 0.27698, 0.46153, 0.93309, 0.27680,\n    0.47151, 0.94214, 0.27648, 0.48144, 0.95064, 0.27603, 0.49132, 0.95857,\n    0.27543, 0.50115, 0.96594, 0.27469, 0.51094, 0.97275, 0.27381, 0.52069,\n    0.97899, 0.27273, 0.53040, 0.98461, 0.27106, 0.54015, 0.98930, 0.26878,\n    0.54995, 0.99303, 0.26592, 0.55979, 0.99583, 0.26252, 0.56967, 0.99773,\n    0.25862, 0.57958, 0.99876, 0.25425, 0.58950, 0.99896, 0.24946, 0.59943,\n    0.99835, 0.24427, 0.60937, 0.99697, 0.23874, 0.61931, 0.99485, 0.23288,\n    0.62923, 0.99202, 0.22676, 0.63913, 0.98851, 0.22039, 0.64901, 0.98436,\n    0.21382, 0.65886, 0.97959, 0.20708, 0.66866, 0.97423, 0.20021, 0.67842,\n    0.96833, 0.19326, 0.68812, 0.96190, 0.18625, 0.69775, 0.95498, 0.17923,\n    0.70732, 0.94761, 0.17223, 0.71680, 0.93981, 0.16529, 0.72620, 0.93161,\n    0.15844, 0.73551, 0.92305, 0.15173, 0.74472, 0.91416, 0.14519, 0.75381,\n    0.90496, 0.13886, 0.76279, 0.89550, 0.13278, 0.77165, 0.88580, 0.12698,\n    0.78037, 0.87590, 0.12151, 0.78896, 0.86581, 0.11639, 0.79740, 0.85559,\n    0.11167, 0.80569, 0.84525, 0.10738, 0.81381, 0.83484, 0.10357, 0.82177,\n    0.82437, 0.10026, 0.82955, 0.81389, 0.09750, 0.83714, 0.80342, 0.09532,\n    0.84455, 0.79299, 0.09377, 0.85175, 0.78264, 0.09287, 0.85875, 0.77240,\n    0.09267, 0.86554, 0.76230, 0.09320, 0.87211, 0.75237, 0.09451, 0.87844,\n    0.74265, 0.09662, 0.88454, 0.73316, 0.09958, 0.89040, 0.72393, 0.10342,\n    0.89600, 0.71500, 0.10815, 0.90142, 0.70599, 0.11374, 0.90673, 0.69651,\n    0.12014, 0.91193, 0.68660, 0.12733, 0.91701, 0.67627, 0.13526, 0.92197,\n    0.66556, 0.14391, 0.92680, 0.65448, 0.15323, 0.93151, 0.64308, 0.16319,\n    0.93609, 0.63137, 0.17377, 0.94053, 0.61938, 0.18491, 0.94484, 0.60713,\n    0.19659, 0.94901, 0.59466, 0.20877, 0.95304, 0.58199, 0.22142, 0.95692,\n    0.56914, 0.23449, 0.96065, 0.55614, 0.24797, 0.96423, 0.54303, 0.26180,\n    0.96765, 0.52981, 0.27597, 0.97092, 0.51653, 0.29042, 0.97403, 0.50321,\n    0.30513, 0.97697, 0.48987, 0.32006, 0.97974, 0.47654, 0.33517, 0.98234,\n    0.46325, 0.35043, 0.98477, 0.45002, 0.36581, 0.98702, 0.43688, 0.38127,\n    0.98909, 0.42386, 0.39678, 0.99098, 0.41098, 0.41229, 0.99268, 0.39826,\n    0.42778, 0.99419, 0.38575, 0.44321, 0.99551, 0.37345, 0.45854, 0.99663,\n    0.36140, 0.47375, 0.99755, 0.34963, 0.48879, 0.99828, 0.33816, 0.50362,\n    0.99879, 0.32701, 0.51822, 0.99910, 0.31622, 0.53255, 0.99919, 0.30581,\n    0.54658, 0.99907, 0.29581, 0.56026, 0.99873, 0.28623, 0.57357, 0.99817,\n    0.27712, 0.58646, 0.99739, 0.26849, 0.59891, 0.99638, 0.26038, 0.61088,\n    0.99514, 0.25280, 0.62233, 0.99366, 0.24579, 0.63323, 0.99195, 0.23937,\n    0.64362, 0.98999, 0.23356, 0.65394, 0.98775, 0.22835, 0.66428, 0.98524,\n    0.22370, 0.67462, 0.98246, 0.21960, 0.68494, 0.97941, 0.21602, 0.69525,\n    0.97610, 0.21294, 0.70553, 0.97255, 0.21032, 0.71577, 0.96875, 0.20815,\n    0.72596, 0.96470, 0.20640, 0.73610, 0.96043, 0.20504, 0.74617, 0.95593,\n    0.20406, 0.75617, 0.95121, 0.20343, 0.76608, 0.94627, 0.20311, 0.77591,\n    0.94113, 0.20310, 0.78563, 0.93579, 0.20336, 0.79524, 0.93025, 0.20386,\n    0.80473, 0.92452, 0.20459, 0.81410, 0.91861, 0.20552, 0.82333, 0.91253,\n    0.20663, 0.83241, 0.90627, 0.20788, 0.84133, 0.89986, 0.20926, 0.85010,\n    0.89328, 0.21074, 0.85868, 0.88655, 0.21230, 0.86709, 0.87968, 0.21391,\n    0.87530, 0.87267, 0.21555, 0.88331, 0.86553, 0.21719, 0.89112, 0.85826,\n    0.21880, 0.89870, 0.85087, 0.22038, 0.90605, 0.84337, 0.22188, 0.91317,\n    0.83576, 0.22328, 0.92004, 0.82806, 0.22456, 0.92666, 0.82025, 0.22570,\n    0.93301, 0.81236, 0.22667, 0.93909, 0.80439, 0.22744, 0.94489, 0.79634,\n    0.22800, 0.95039, 0.78823, 0.22831, 0.95560, 0.78005, 0.22836, 0.96049,\n    0.77181, 0.22811, 0.96507, 0.76352, 0.22754, 0.96931, 0.75519, 0.22663,\n    0.97323, 0.74682, 0.22536, 0.97679, 0.73842, 0.22369, 0.98000, 0.73000,\n    0.22161, 0.98289, 0.72140, 0.21918, 0.98549, 0.71250, 0.21650, 0.98781,\n    0.70330, 0.21358, 0.98986, 0.69382, 0.21043, 0.99163, 0.68408, 0.20706,\n    0.99314, 0.67408, 0.20348, 0.99438, 0.66386, 0.19971, 0.99535, 0.65341,\n    0.19577, 0.99607, 0.64277, 0.19165, 0.99654, 0.63193, 0.18738, 0.99675,\n    0.62093, 0.18297, 0.99672, 0.60977, 0.17842, 0.99644, 0.59846, 0.17376,\n    0.99593, 0.58703, 0.16899, 0.99517, 0.57549, 0.16412, 0.99419, 0.56386,\n    0.15918, 0.99297, 0.55214, 0.15417, 0.99153, 0.54036, 0.14910, 0.98987,\n    0.52854, 0.14398, 0.98799, 0.51667, 0.13883, 0.98590, 0.50479, 0.13367,\n    0.98360, 0.49291, 0.12849, 0.98108, 0.48104, 0.12332, 0.97837, 0.46920,\n    0.11817, 0.97545, 0.45740, 0.11305, 0.97234, 0.44565, 0.10797, 0.96904,\n    0.43399, 0.10294, 0.96555, 0.42241, 0.09798, 0.96187, 0.41093, 0.09310,\n    0.95801, 0.39958, 0.08831, 0.95398, 0.38836, 0.08362, 0.94977, 0.37729,\n    0.07905, 0.94538, 0.36638, 0.07461, 0.94084, 0.35566, 0.07031, 0.93612,\n    0.34513, 0.06616, 0.93125, 0.33482, 0.06218, 0.92623, 0.32473, 0.05837,\n    0.92105, 0.31489, 0.05475, 0.91572, 0.30530, 0.05134, 0.91024, 0.29599,\n    0.04814, 0.90463, 0.28696, 0.04516, 0.89888, 0.27824, 0.04243, 0.89298,\n    0.26981, 0.03993, 0.88691, 0.26152, 0.03753, 0.88066, 0.25334, 0.03521,\n    0.87422, 0.24526, 0.03297, 0.86760, 0.23730, 0.03082, 0.86079, 0.22945,\n    0.02875, 0.85380, 0.22170, 0.02677, 0.84662, 0.21407, 0.02487, 0.83926,\n    0.20654, 0.02305, 0.83172, 0.19912, 0.02131, 0.82399, 0.19182, 0.01966,\n    0.81608, 0.18462, 0.01809, 0.80799, 0.17753, 0.01660, 0.79971, 0.17055,\n    0.01520, 0.79125, 0.16368, 0.01387, 0.78260, 0.15693, 0.01264, 0.77377,\n    0.15028, 0.01148, 0.76476, 0.14374, 0.01041, 0.75556, 0.13731, 0.00942,\n    0.74617, 0.13098, 0.00851, 0.73661, 0.12477, 0.00769, 0.72686, 0.11867,\n    0.00695, 0.71692, 0.11268, 0.00629, 0.70680, 0.10680, 0.00571, 0.69650,\n    0.10102, 0.00522, 0.68602, 0.09536, 0.00481, 0.67535, 0.08980, 0.00449,\n    0.66449, 0.08436, 0.00424, 0.65345, 0.07902, 0.00408, 0.64223, 0.07380,\n    0.00401, 0.63082, 0.06868, 0.00401, 0.61923, 0.06367, 0.00410, 0.60746,\n    0.05878, 0.00427, 0.59550, 0.05399, 0.00453, 0.58336, 0.04931, 0.00486,\n    0.57103, 0.04474, 0.00529, 0.55852, 0.04028, 0.00579, 0.54583, 0.03593,\n    0.00638, 0.53295, 0.03169, 0.00705, 0.51989, 0.02756, 0.00780, 0.50664,\n    0.02354, 0.00863, 0.49321, 0.01963, 0.00955, 0.47960, 0.01583, 0.01055};\n\nradfoam::CMapTable upload_cmap_data() {\n    radfoam::CMapTable cmap_table;\n    float *data[NUM_CMAPS];\n    int sizes[NUM_CMAPS];\n\n    cuda_check(cuMemAlloc_v2(reinterpret_cast<CUdeviceptr *>(&data[0]),\n                             sizeof(gray_data)));\n    cuda_check(cuMemcpyHtoD_v2(\n        reinterpret_cast<CUdeviceptr>(data[0]), gray_data, sizeof(gray_data)));\n    sizes[0] = sizeof(gray_data) / (3 * sizeof(float));\n\n    cuda_check(cuMemAlloc_v2(reinterpret_cast<CUdeviceptr *>(&data[1]),\n                             sizeof(viridis_data)));\n    cuda_check(cuMemcpyHtoD_v2(reinterpret_cast<CUdeviceptr>(data[1]),\n                               viridis_data,\n                               sizeof(viridis_data)));\n    sizes[1] = sizeof(viridis_data) / (3 * sizeof(float));\n\n    cuda_check(cuMemAlloc_v2(reinterpret_cast<CUdeviceptr *>(&data[2]),\n                             sizeof(inferno_data)));\n    cuda_check(cuMemcpyHtoD_v2(reinterpret_cast<CUdeviceptr>(data[2]),\n                               inferno_data,\n                               sizeof(inferno_data)));\n    sizes[2] = sizeof(inferno_data) / (3 * sizeof(float));\n\n    cuda_check(cuMemAlloc_v2(reinterpret_cast<CUdeviceptr *>(&data[3]),\n                             sizeof(turbo_data)));\n    cuda_check(cuMemcpyHtoD_v2(reinterpret_cast<CUdeviceptr>(data[3]),\n                               turbo_data,\n                               sizeof(turbo_data)));\n    sizes[3] = sizeof(turbo_data) / (3 * sizeof(float));\n\n    CUdeviceptr data_ptr;\n    cuda_check(cuMemAlloc_v2(&data_ptr, NUM_CMAPS * sizeof(float *)));\n    cuda_check(cuMemcpyHtoD_v2(data_ptr, data, NUM_CMAPS * sizeof(float *)));\n    cmap_table.data = reinterpret_cast<float **>(data_ptr);\n\n    CUdeviceptr sizes_ptr;\n    cuda_check(cuMemAlloc_v2(&sizes_ptr, NUM_CMAPS * sizeof(int)));\n    cuda_check(cuMemcpyHtoD_v2(sizes_ptr, sizes, NUM_CMAPS * sizeof(int)));\n    cmap_table.sizes = reinterpret_cast<int *>(sizes_ptr);\n\n    return cmap_table;\n}\n\n} // namespace\n\nstruct ViewerPrivate : public Viewer {\n    std::shared_ptr<Pipeline> pipeline;\n\n    ViewerOptions options;\n    Camera camera;\n\n    GLFWwindow *window;\n    GLuint program;\n    GLuint texture;\n    CUcontext cuda_context;\n    CUstream cuda_stream;\n    CUdevice gl_device;\n    CUgraphicsResource resource;\n    CMapTable cmap_table;\n\n    uint32_t num_points;\n    uint32_t num_point_adjacency;\n    CUDAArray<uint8_t> points_buffer;\n    CUDAArray<uint8_t> attrs_buffer;\n    CUDAArray<uint8_t> point_adjacency_buffer;\n    CUDAArray<uint8_t> point_adjacency_offsets_buffer;\n    CUDAArray<uint8_t> adjacent_diff_buffer;\n    std::vector<uint8_t> points_cpu;\n    std::vector<uint8_t> aabb_tree_cpu;\n\n    // New members for fallback\n    bool is_cuda_gl_interop_supported;\n    std::vector<uint8_t> cpu_fallback_buffer;\n\n    std::mutex scene_mutex;\n    std::condition_variable scene_cv;\n\n    std::atomic_bool closed;\n    std::atomic_bool paused;\n    std::atomic_bool should_step;\n    std::atomic_int iteration;\n    std::atomic_bool training;\n    std::atomic_bool scene_updating;\n\n    ViewerPrivate(std::shared_ptr<Pipeline> pipeline, ViewerOptions options)\n        : pipeline(pipeline), options(options),\n          is_cuda_gl_interop_supported(false), scene_mutex() {\n\n        glfwSetErrorCallback(glfwErrorCallback);\n        if (!glfwInit()) {\n            throw std::runtime_error(\"GLFW initialization failed\");\n        }\n\n        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);\n        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);\n        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);\n\n        window =\n            glfwCreateWindow(1920, 1080, \"RadFoam Viewer\", nullptr, nullptr);\n        if (!window) {\n            glfwTerminate();\n            throw std::runtime_error(\"GLFW window creation failed\");\n        }\n        glfwSetWindowUserPointer(window, this);\n        glfwSetFramebufferSizeCallback(window, &ViewerPrivate::handle_resize);\n        glfwSetKeyCallback(window, &ViewerPrivate::handle_key);\n\n        if (!gl3w_initialized) {\n            if (!gl3wInit()) {\n                throw std::runtime_error(\"GL3W initialization failed\");\n            }\n            gl3w_initialized = true;\n        }\n\n        cmap_table = upload_cmap_data();\n\n        num_points = 0;\n        num_point_adjacency = 0;\n\n        closed = false;\n        paused = true;\n        should_step = false;\n        iteration = 0;\n        training = false;\n        scene_updating = false;\n\n        glfwMakeContextCurrent(window);\n        glfwSwapInterval(0);\n\n#ifdef GPU_DEBUG\n        glEnable(GL_DEBUG_OUTPUT);\n        glDebugMessageCallback(gl_debug_callback, nullptr);\n#endif\n\n        uint32_t gl_device_count;\n        CUdevice cuda_devices[16];\n        CUresult res = cuGLGetDevices(\n            &gl_device_count, cuda_devices, 16, CU_GL_DEVICE_LIST_ALL);\n        if (res != CUDA_SUCCESS || gl_device_count == 0) {\n            is_cuda_gl_interop_supported = false;\n            // Fallback to CPU transfer: use device 0 by default\n            cuda_check(cuDeviceGet(&gl_device, 0));\n        } else if (gl_device_count > 1) {\n            throw std::runtime_error(\"multiple CUDA-GL interop devices found, \"\n                                     \"this is not currently supported\");\n        } else {\n            is_cuda_gl_interop_supported = true;\n            gl_device = cuda_devices[0];\n        }\n\n        cuda_check(cuDevicePrimaryCtxRetain(&cuda_context, gl_device));\n        cuda_check(cuCtxPushCurrent(cuda_context));\n        cuda_check(cuStreamCreate(&cuda_stream, CU_STREAM_NON_BLOCKING));\n        cuda_check(cuCtxPopCurrent(nullptr));\n\n        int width, height;\n        glfwGetFramebufferSize(window, &width, &height);\n        camera = look_at(options.camera_pos,\n                         options.camera_pos + options.camera_forward,\n                         options.camera_up,\n                         0.7f,\n                         width,\n                         height);\n        program = create_program();\n        texture = allocate_texture(width, height);\n        if (is_cuda_gl_interop_supported) {\n            resource = register_texture(texture);\n        }\n    }\n\n    ~ViewerPrivate() {\n        if (is_cuda_gl_interop_supported) {\n            cuda_check(cuGraphicsUnregisterResource(resource));\n        }\n        gl_check(glDeleteTextures(1, &texture));\n        gl_check(glDeleteProgram(program));\n        glfwDestroyWindow(window);\n    }\n\n    void run() {\n        glfwMakeContextCurrent(window);\n\n        cuda_check(cuCtxPushCurrent(cuda_context));\n\n        IMGUI_CHECKVERSION();\n        ImGui::CreateContext();\n        ImGuiIO &io = ImGui::GetIO();\n        (void)io;\n        io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;\n        io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;\n        io.IniFilename = nullptr;\n\n        ImGui::StyleColorsLight();\n\n        ImGui_ImplGlfw_InitForOpenGL(window, true);\n        gl_check(ImGui_ImplOpenGL3_Init(\"#version 130\"));\n\n        gl_check(glActiveTexture(GL_TEXTURE0));\n        gl_check(glUseProgram(program));\n        gl_check(glUniform1i(glGetUniformLocation(program, \"frame\"), 0));\n\n        GLuint array;\n        gl_check(glGenVertexArrays(1, &array));\n        gl_check(glBindVertexArray(array));\n\n        TraceSettings settings = default_trace_settings();\n        settings.weight_threshold = 0.05f;\n        VisualizationSettings vis_settings = default_visualization_settings();\n\n        auto last_frame_time = std::chrono::high_resolution_clock::now();\n        float delta_t = 0.0f;\n        float frame_rate = 0.0f;\n\n        double mouse_x, mouse_y;\n        glfwGetCursorPos(window, &mouse_x, &mouse_y);\n\n        std::unique_lock<std::mutex> lock(scene_mutex);\n\n        while (!glfwWindowShouldClose(window)) {\n            glfwPollEvents();\n\n            if (!io.WantCaptureKeyboard) {\n                Vec3f position_delta(0, 0, 0);\n                if (glfwGetKey(window, GLFW_KEY_W)) {\n                    position_delta += *camera.forward;\n                }\n                if (glfwGetKey(window, GLFW_KEY_S)) {\n                    position_delta -= *camera.forward;\n                }\n                if (glfwGetKey(window, GLFW_KEY_A)) {\n                    position_delta -= *camera.right;\n                }\n                if (glfwGetKey(window, GLFW_KEY_D)) {\n                    position_delta += *camera.right;\n                }\n                if (!io.WantCaptureMouse) {\n                    if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)) {\n                        position_delta += *camera.up;\n                    }\n                    if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL)) {\n                        position_delta -= *camera.up;\n                    }\n                }\n                float speed = 2.0f * delta_t;\n                Vec3f new_pos = *camera.position + speed * position_delta;\n                camera.position = new_pos;\n            }\n\n            if (!io.WantCaptureMouse) {\n                ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);\n                double last_x = mouse_x;\n                double last_y = mouse_y;\n                glfwGetCursorPos(window, &mouse_x, &mouse_y);\n\n                double delta_x = mouse_x - last_x;\n                double delta_y = mouse_y - last_y;\n\n                if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT)) {\n                    camera.rotate(options.camera_up, -0.001 * delta_x);\n                    camera.rotate(*camera.right, -0.001 * delta_y);\n                }\n            }\n\n            ImGui_ImplOpenGL3_NewFrame();\n            ImGui_ImplGlfw_NewFrame();\n            ImGui::NewFrame();\n\n            ImGui::SetNextWindowSize(ImVec2(400, 440), ImGuiCond_FirstUseEver);\n            ImGui::Begin(\"Controls\");\n\n            if (training.load()) {\n                ImGui::SeparatorText(\"Training\");\n\n                ImGui::Text(\"Iteration controls: \");\n                ImGui::SameLine();\n                if (ImGui::Button(paused ? \">\" : \"||\")) {\n                    paused = !paused;\n                }\n                if (paused) {\n                    ImGui::SameLine();\n                    bool disabled = should_step;\n                    if (disabled) {\n                        ImGui::BeginDisabled();\n                    }\n                    if (ImGui::Button(\">|\")) {\n                        should_step = true;\n                    }\n                    if (disabled) {\n                        ImGui::EndDisabled();\n                    }\n                }\n\n                if (options.total_iterations > 0) {\n                    ImGui::ProgressBar(float(iteration.load()) /\n                                           options.total_iterations,\n                                       ImVec2(0.0f, 0.0f));\n                    ImGui::SameLine();\n                    ImGui::Text(\n                        \"%d / %d\", iteration.load(), options.total_iterations);\n                } else {\n                    ImGui::Text(\"Iteration: %d\", iteration.load());\n                }\n            }\n\n            ImGui::SeparatorText(\"Viewer settings\");\n\n            ImGui::Text(\"Resolution: %dx%d\", camera.width, camera.height);\n\n            float fov_degrees = camera.fov * 180.0f / M_PI;\n            ImGui::SliderFloat(\"Field of view\",\n                               &fov_degrees,\n                               25.0f,\n                               160.0f,\n                               \"%.0f°\",\n                               ImGuiSliderFlags_Logarithmic);\n            camera.fov = fov_degrees * M_PI / 180.0f;\n\n            const char *camera_models[] = {\"Pinhole\", \"Fisheye\"};\n\n            ImGui::Combo(\"Camera model\",\n                         reinterpret_cast<int *>(&camera.model),\n                         camera_models,\n                         IM_ARRAYSIZE(camera_models));\n\n            ImGui::Text(\"Frame rate: %d frames/s\", int(frame_rate + 0.5f));\n            ImGui::Checkbox(\"Limit viewer frame rate while training\",\n                            &options.limit_framerate);\n            if (options.limit_framerate) {\n                ImGui::SliderInt(\n                    \"Max frame rate\", &options.max_framerate, 1, 240);\n            }\n\n            ImGui::SeparatorText(\"Trace settings\");\n            ImGui::SliderFloat(\"Weight threshold\",\n                               &settings.weight_threshold,\n                               1e-3,\n                               1e0,\n                               \"%.4f\",\n                               ImGuiSliderFlags_Logarithmic |\n                                   ImGuiSliderFlags_NoRoundToFormat);\n            ImGui::SliderInt(\n                \"Max intersections\",\n                reinterpret_cast<int *>(&settings.max_intersections),\n                1,\n                1024,\n                \"%d\",\n                ImGuiSliderFlags_Logarithmic);\n\n            ImGui::SeparatorText(\"Visualization settings\");\n\n            const char *modes[] = {\"RGB\", \"Depth\", \"Alpha\", \"Intersections\"};\n            ImGui::Combo(\"Mode\",\n                         reinterpret_cast<int *>(&vis_settings.mode),\n                         modes,\n                         IM_ARRAYSIZE(modes));\n\n            if (vis_settings.mode == VisualizationMode::Depth ||\n                vis_settings.mode == VisualizationMode::Intersections) {\n                const char *color_maps[] = {\n                    \"Gray\", \"Viridis\", \"Inferno\", \"Turbo\"};\n                ImGui::Combo(\"Color map\",\n                             reinterpret_cast<int *>(&vis_settings.color_map),\n                             color_maps,\n                             IM_ARRAYSIZE(color_maps));\n            }\n\n            if (vis_settings.mode == VisualizationMode::RGB) {\n                ImGui::Checkbox(\"Checkerboard background\",\n                                &vis_settings.checker_bg);\n                if (!vis_settings.checker_bg) {\n                    ImGui::ColorEdit3(\n                        \"Background color\",\n                        reinterpret_cast<float *>(&vis_settings.bg_color));\n                }\n            }\n\n            if (vis_settings.mode == VisualizationMode::Depth) {\n                ImGui::SliderFloat(\"Max depth\",\n                                   &vis_settings.max_depth,\n                                   1e-5,\n                                   1e3,\n                                   \"%.4f\",\n                                   ImGuiSliderFlags_Logarithmic |\n                                       ImGuiSliderFlags_NoRoundToFormat);\n                float percentile = vis_settings.depth_quantile * 100.0f;\n                ImGui::SliderFloat(\n                    \"Depth percentile\", &percentile, 0.0f, 100.0f, \"%.0f\\%\");\n                vis_settings.depth_quantile = percentile / 100.0f;\n            }\n\n            gl_check(glViewport(0, 0, camera.width, camera.height));\n            gl_check(glClear(GL_COLOR_BUFFER_BIT));\n\n            if (num_point_adjacency > 0) {\n                uint32_t start_index = nn_cpu(ScalarType::Float32,\n                                              points_cpu.data(),\n                                              aabb_tree_cpu.data(),\n                                              *camera.position,\n                                              num_points);\n                CUarray output_array = nullptr;\n                CUsurfObject output_surface = 0;\n                if (is_cuda_gl_interop_supported) {\n                    cuda_check(cuGraphicsMapResources(1, &resource, 0));\n                    cuda_check(cuGraphicsSubResourceGetMappedArray(\n                        &output_array, resource, 0, 0));\n                } else {\n                    CUDA_ARRAY_DESCRIPTOR arrDesc = {};\n                    arrDesc.Format = CU_AD_FORMAT_UNSIGNED_INT8;\n                    arrDesc.NumChannels = 4;\n                    arrDesc.Width = camera.width;\n                    arrDesc.Height = camera.height;\n                    cuda_check(cuArrayCreate(&output_array, &arrDesc));\n                }\n\n                CUDA_RESOURCE_DESC res_desc = {};\n                res_desc.resType = CU_RESOURCE_TYPE_ARRAY;\n                res_desc.res.array.hArray = output_array;\n                cuda_check(cuSurfObjectCreate(&output_surface, &res_desc));\n\n                pipeline->trace_visualization(\n                    settings,\n                    vis_settings,\n                    camera,\n                    cmap_table,\n                    num_points,\n                    num_point_adjacency,\n                    points_buffer.begin(),\n                    attrs_buffer.begin(),\n                    point_adjacency_buffer.begin(),\n                    point_adjacency_offsets_buffer.begin(),\n                    adjacent_diff_buffer.begin(),\n                    start_index,\n                    output_surface,\n                    &cuda_stream);\n\n                if (is_cuda_gl_interop_supported) {\n                    cuda_check(cuSurfObjectDestroy(output_surface));\n                    cuda_check(cuGraphicsUnmapResources(1, &resource, 0));\n                } else {\n                    cuda_check(cuStreamSynchronize(cuda_stream));\n                    cuda_check(cuSurfObjectDestroy(output_surface));\n\n                    size_t buffer_size =\n                        camera.width * camera.height * 4; // RGBA8\n                    if (cpu_fallback_buffer.size() != buffer_size) {\n                        cpu_fallback_buffer.resize(buffer_size);\n                    }\n\n                    CUDA_MEMCPY2D copyParam = {0};\n                    copyParam.srcXInBytes = 0;\n                    copyParam.srcY = 0;\n                    copyParam.srcMemoryType = CU_MEMORYTYPE_ARRAY;\n                    copyParam.srcArray = output_array;\n                    copyParam.dstXInBytes = 0;\n                    copyParam.dstY = 0;\n                    copyParam.dstMemoryType = CU_MEMORYTYPE_HOST;\n                    copyParam.dstHost = cpu_fallback_buffer.data();\n                    copyParam.WidthInBytes = camera.width * 4;\n                    copyParam.Height = camera.height;\n                    cuda_check(cuMemcpy2D(&copyParam));\n                    cuda_check(cuArrayDestroy(output_array));\n                }\n\n                gl_check(glBindTexture(GL_TEXTURE_2D, texture));\n                gl_check(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));\n                if (!is_cuda_gl_interop_supported) {\n                    gl_check(glTexImage2D(GL_TEXTURE_2D,\n                                          0,\n                                          GL_RGBA8,\n                                          camera.width,\n                                          camera.height,\n                                          0,\n                                          GL_RGBA,\n                                          GL_UNSIGNED_BYTE,\n                                          cpu_fallback_buffer.data()));\n                }\n                gl_check(glBindTexture(GL_TEXTURE_2D, 0));\n\n                if (is_cuda_gl_interop_supported) {\n                    cuda_check(cuStreamSynchronize(cuda_stream));\n                } else {\n                    cuda_check(cuStreamSynchronize(0));\n                }\n            }\n\n            ImGui::End();\n\n            ImGui::Render();\n            ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());\n\n            glfwSwapBuffers(window);\n\n            auto frame_duration =\n                std::chrono::high_resolution_clock::now() - last_frame_time;\n            auto now = std::chrono::high_resolution_clock::now();\n\n            if (options.limit_framerate && !paused) {\n                float min_frame_duration = 1.0f / options.max_framerate;\n                while (std::chrono::duration_cast<std::chrono::duration<float>>(\n                           frame_duration)\n                           .count() < min_frame_duration) {\n                    std::this_thread::yield();\n                    now = std::chrono::high_resolution_clock::now();\n                    frame_duration = now - last_frame_time;\n\n                    if (scene_updating) {\n                        cuda_check(cuStreamSynchronize(cuda_stream));\n                        scene_cv.wait(lock, [&] { return !scene_updating; });\n                    }\n                }\n            }\n\n            last_frame_time = now;\n            float frame_duration_seconds =\n                std::chrono::duration_cast<std::chrono::duration<float>>(\n                    frame_duration)\n                    .count();\n            float w = 1000.0f * frame_duration_seconds * frame_duration_seconds;\n            w = std::min(1.0f, w);\n            frame_rate = (1.0f - w) * frame_rate + w / frame_duration_seconds;\n\n            delta_t = frame_duration_seconds;\n\n            if (scene_updating) {\n                cuda_check(cuStreamSynchronize(cuda_stream));\n                scene_cv.wait(lock, [&] { return !scene_updating; });\n            }\n        }\n\n        cuda_check(cuCtxPopCurrent(nullptr));\n\n        glfwHideWindow(window);\n        closed = true;\n        paused = false;\n    }\n\n    void update_scene(uint32_t num_points,\n                      uint32_t num_attrs,\n                      uint32_t num_point_adjacency,\n                      const void *coords,\n                      const void *attributes,\n                      const void *point_adjacency,\n                      const void *point_adjacency_offsets,\n                      const void *aabb_tree) override {\n        scene_updating = true;\n        {\n            auto lock = std::lock_guard(scene_mutex);\n\n            this->num_points = num_points;\n            this->num_point_adjacency = num_point_adjacency;\n\n            size_t coord_scalar_size = sizeof(float);\n            size_t attr_scalar_size = scalar_size(pipeline->attribute_type());\n\n            size_t coord_bytes = num_points * coord_scalar_size * 3;\n            size_t attr_bytes =\n                num_attrs * attr_scalar_size * pipeline->attribute_dim();\n            size_t point_adjacency_bytes =\n                num_point_adjacency * sizeof(uint32_t);\n            size_t point_adjacency_offsets_bytes =\n                (num_points + 1) * sizeof(uint32_t);\n            size_t adjacent_diff_bytes = (num_point_adjacency + 32) * 8;\n            size_t aabb_tree_bytes =\n                pow2_round_up(num_points) * coord_scalar_size * 6;\n\n            points_buffer.resize(coord_bytes);\n            attrs_buffer.resize(attr_bytes);\n            point_adjacency_buffer.resize(point_adjacency_bytes);\n            point_adjacency_offsets_buffer.resize(\n                point_adjacency_offsets_bytes);\n            adjacent_diff_buffer.resize(adjacent_diff_bytes);\n\n            points_cpu.resize(coord_bytes);\n            aabb_tree_cpu.resize(aabb_tree_bytes);\n\n            cuda_check(cuMemcpyDtoD((CUdeviceptr)points_buffer.begin(),\n                                    (CUdeviceptr)coords,\n                                    coord_bytes));\n            cuda_check(cuMemcpyDtoD((CUdeviceptr)attrs_buffer.begin(),\n                                    (CUdeviceptr)attributes,\n                                    attr_bytes));\n            cuda_check(cuMemcpyDtoD((CUdeviceptr)point_adjacency_buffer.begin(),\n                                    (CUdeviceptr)point_adjacency,\n                                    point_adjacency_bytes));\n            cuda_check(cuMemcpyDtoD(\n                (CUdeviceptr)point_adjacency_offsets_buffer.begin(),\n                (CUdeviceptr)point_adjacency_offsets,\n                point_adjacency_offsets_bytes));\n\n            cuda_check(cuMemcpyDtoH(points_cpu.data(),\n                                    (CUdeviceptr)points_buffer.begin(),\n                                    coord_bytes));\n            cuda_check(cuMemcpyDtoH(\n                aabb_tree_cpu.data(), (CUdeviceptr)aabb_tree, aabb_tree_bytes));\n\n            prefetch_adjacent_diff(\n                reinterpret_cast<const Vec3f *>(coords),\n                num_points,\n                num_point_adjacency,\n                reinterpret_cast<const uint32_t *>(point_adjacency),\n                reinterpret_cast<const uint32_t *>(point_adjacency_offsets),\n                reinterpret_cast<Vec4h *>(adjacent_diff_buffer.begin()),\n                nullptr);\n\n            cuda_check(cuStreamSynchronize(0));\n\n            scene_updating = false;\n        }\n        scene_cv.notify_one();\n    }\n\n    void step(int iteration) override {\n        if (should_step) {\n            should_step = false;\n        }\n        this->training = true;\n        this->iteration = iteration;\n        while (paused) {\n            std::this_thread::yield();\n            if (should_step) {\n                break;\n            }\n        }\n    }\n\n    bool is_closed() const override { return closed; }\n\n    const Pipeline &get_pipeline() const override { return *pipeline; }\n\n    static void handle_resize(GLFWwindow *window, int width, int height) {\n        ViewerPrivate *self =\n            static_cast<ViewerPrivate *>(glfwGetWindowUserPointer(window));\n\n        self->camera.width = width;\n        self->camera.height = height;\n\n        if (self->is_cuda_gl_interop_supported) {\n            cuda_check(cuGraphicsUnregisterResource(self->resource));\n        }\n        gl_check(glDeleteTextures(1, &self->texture));\n        self->texture = allocate_texture(width, height);\n        if (self->is_cuda_gl_interop_supported) {\n            self->resource = register_texture(self->texture);\n        }\n    }\n\n    static void handle_key(\n        GLFWwindow *window, int key, int scancode, int action, int mods) {\n        ViewerPrivate *self =\n            static_cast<ViewerPrivate *>(glfwGetWindowUserPointer(window));\n\n        if (action == GLFW_PRESS) {\n            if (key == GLFW_KEY_SPACE) {\n                self->paused = !self->paused;\n            }\n        }\n    }\n};\n\nvoid run_with_viewer(std::shared_ptr<Pipeline> pipeline,\n                     std::function<void(std::shared_ptr<Viewer>)> callback,\n                     ViewerOptions options) {\n    auto viewer = std::make_shared<ViewerPrivate>(std::move(pipeline), options);\n\n    auto thread_fn = [&]() { callback(viewer); };\n\n    std::thread bg_thread(thread_fn);\n    try {\n        viewer->run();\n    } catch (const std::exception &e) {\n        std::cerr << \"Exception in viewer thread: \" << e.what() << std::endl;\n    }\n    bg_thread.join();\n}\n\n} // namespace radfoam\n"
  },
  {
    "path": "src/viewer/viewer.h",
    "content": "#pragma once\n\n#include <functional>\n#include <memory>\n\n#include \"../tracing/pipeline.h\"\n\nnamespace radfoam {\n\nstruct ViewerOptions {\n    bool limit_framerate;\n    int max_framerate;\n    int total_iterations;\n    Vec3f camera_pos;\n    Vec3f camera_forward;\n    Vec3f camera_up;\n};\n\ninline ViewerOptions default_viewer_options() {\n    ViewerOptions options;\n    options.limit_framerate = true;\n    options.max_framerate = 20;\n    options.total_iterations = 0;\n    options.camera_pos = Vec3f(2.5f, 2.5f, 2.5f);\n    options.camera_forward = Vec3f(-1.0f, -1.0f, -1.0f).normalized();\n    options.camera_up = Vec3f(0.0f, 0.0f, 1.0f);\n    return options;\n}\n\nclass Viewer {\n  public:\n    ~Viewer() = default;\n\n    virtual void update_scene(uint32_t num_points,\n                              uint32_t num_attrs,\n                              uint32_t num_point_adjacency,\n                              const void *coords,\n                              const void *attributes,\n                              const void *point_adjacency,\n                              const void *point_adjacency_offsets,\n                              const void *aabb_tree) = 0;\n\n    virtual void step(int iteration) = 0;\n\n    virtual bool is_closed() const = 0;\n\n    virtual const Pipeline &get_pipeline() const = 0;\n};\n\nvoid run_with_viewer(std::shared_ptr<Pipeline> pipeline,\n                     std::function<void(std::shared_ptr<Viewer>)> callback,\n                     ViewerOptions options);\n\n} // namespace radfoam"
  },
  {
    "path": "test.py",
    "content": "import numpy as np\nfrom PIL import Image\nimport configargparse\nimport warnings\n\nwarnings.filterwarnings(\"ignore\")\n\nimport torch\n\nfrom data_loader import DataHandler\nfrom configs import *\nfrom radfoam_model.scene import RadFoamScene\nfrom radfoam_model.utils import psnr\nimport radfoam\n\n\nseed = 42\ntorch.random.manual_seed(seed)\nnp.random.seed(seed)\n\n\ndef test(args, pipeline_args, model_args, optimizer_args, dataset_args):\n    checkpoint = args.config.replace(\"/config.yaml\", \"\")\n    os.makedirs(os.path.join(checkpoint, \"test\"), exist_ok=True)\n    device = torch.device(args.device)\n\n    test_data_handler = DataHandler(\n        dataset_args, rays_per_batch=0, device=device\n    )\n    test_data_handler.reload(\n        split=\"test\", downsample=min(dataset_args.downsample)\n    )\n    test_ray_batch_fetcher = radfoam.BatchFetcher(\n        test_data_handler.rays, batch_size=1, shuffle=False\n    )\n    test_rgb_batch_fetcher = radfoam.BatchFetcher(\n        test_data_handler.rgbs, batch_size=1, shuffle=False\n    )\n\n    # Setting up model\n    model = RadFoamScene(args=model_args, device=device)\n\n    model.load_pt(f\"{checkpoint}/model.pt\")\n\n    def test_render(\n        test_data_handler, ray_batch_fetcher, rgb_batch_fetcher\n    ):\n        rays = test_data_handler.rays\n        points, _, _, _ = model.get_trace_data()\n        start_points = model.get_starting_point(\n            rays[:, 0, 0].cuda(), points, model.aabb_tree\n        )\n\n        psnr_list = []\n        with torch.no_grad():\n            for i in range(rays.shape[0]):\n                ray_batch = ray_batch_fetcher.next()[0]\n                rgb_batch = rgb_batch_fetcher.next()[0]\n                output, _, _, _, _ = model(ray_batch, start_points[i])\n\n                # White background\n                opacity = output[..., -1:]\n                rgb_output = output[..., :3] + (1 - opacity)\n                rgb_output = rgb_output.reshape(*rgb_batch.shape).clip(0, 1)\n\n                img_psnr = psnr(rgb_output, rgb_batch).mean()\n                psnr_list.append(img_psnr)\n                torch.cuda.synchronize()\n\n                error = np.uint8((rgb_output - rgb_batch).cpu().abs() * 255)\n                rgb_output = np.uint8(rgb_output.cpu() * 255)\n                rgb_batch = np.uint8(rgb_batch.cpu() * 255)\n\n                im = Image.fromarray(\n                    np.concatenate([rgb_output, rgb_batch, error], axis=1)\n                )\n                im.save(\n                    f\"{checkpoint}/test/rgb_{i:03d}_psnr_{img_psnr:.3f}.png\"\n                )\n\n        average_psnr = sum(psnr_list) / len(psnr_list)\n\n        f = open(f\"{checkpoint}/metrics.txt\", \"w\")\n        f.write(f\"Average PSNR: {average_psnr}\")\n        f.close()\n\n        return average_psnr\n\n    test_render(\n        test_data_handler, test_ray_batch_fetcher, test_rgb_batch_fetcher\n    )\n\n\ndef main():\n    parser = configargparse.ArgParser()\n\n    model_params = ModelParams(parser)\n    dataset_params = DatasetParams(parser)\n    pipeline_params = PipelineParams(parser)\n    optimization_params = OptimizationParams(parser)\n\n    # Add argument to specify a custom config file\n    parser.add_argument(\n        \"-c\", \"--config\", is_config_file=True, help=\"Path to config file\"\n    )\n\n    # Parse arguments\n    args = parser.parse_args()\n\n    test(\n        args,\n        pipeline_params.extract(args),\n        model_params.extract(args),\n        optimization_params.extract(args),\n        dataset_params.extract(args),\n    )\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "torch_bindings/CMakeLists.txt",
    "content": "execute_process(\n  COMMAND python ${CMAKE_SOURCE_DIR}/scripts/torch_info.py torch\n  OUTPUT_VARIABLE TORCH_VERSION\n  OUTPUT_STRIP_TRAILING_WHITESPACE)\n\nexecute_process(\n  COMMAND python ${CMAKE_SOURCE_DIR}/scripts/torch_info.py cuda\n  OUTPUT_VARIABLE TORCH_CUDA_VERSION\n  OUTPUT_STRIP_TRAILING_WHITESPACE)\n\nif(TORCH_CUDA_VERSION VERSION_EQUAL CUDA_VERSION_STRING)\n  message(STATUS \"CUDA version is: ${CUDA_VERSION_STRING}\")\nelse()\n  message(\n    FATAL_ERROR\n      \"CUDA version found (${CUDA_VERSION_STRING}) does not match the version required by PyTorch (${TORCH_CUDA_VERSION}).\"\n  )\nendif()\n\npybind11_add_module(torch_bindings MODULE torch_bindings.cpp\n                    pipeline_bindings.cpp triangulation_bindings.cpp)\n\ntarget_include_directories(torch_bindings PUBLIC ${CMAKE_SOURCE_DIR}/src)\n\ntarget_link_libraries(torch_bindings PRIVATE torch ${TORCH_PYTHON_LIBRARY}\n                                             radfoam ${GLFW_LIBRARY})\n\ninstall(\n  TARGETS torch_bindings\n  COMPONENT torch_bindings\n  LIBRARY DESTINATION ${RADFOAM_INSTALL_PREFIX}\n  ARCHIVE DESTINATION ${RADFOAM_INSTALL_PREFIX}\n  RUNTIME DESTINATION ${RADFOAM_INSTALL_PREFIX})\n\nconfigure_file(${CMAKE_SOURCE_DIR}/torch_bindings/radfoam/__init__.py.in\n               ${CMAKE_BINARY_DIR}/__init__.py @ONLY)\n\ninstall(FILES ${CMAKE_BINARY_DIR}/__init__.py\n        DESTINATION ${RADFOAM_INSTALL_PREFIX})\n"
  },
  {
    "path": "torch_bindings/bindings.h",
    "content": "#pragma once\n\n#include <array>\n#include <string>\n\n#include <c10/cuda/CUDAStream.h>\n#include <pybind11/functional.h>\n#include <pybind11/pybind11.h>\n#include <pybind11/stl.h>\n#include <torch/extension.h>\n\n#include \"utils/geometry.h\"\n\nnamespace radfoam_bindings {\n\nnamespace py = pybind11;\nusing namespace radfoam;\n\ninline void set_default_stream() {\n    auto stream = at::cuda::getCurrentCUDAStream();\n    at::cuda::setCurrentCUDAStream(stream);\n}\n\ninline ScalarType dtype_to_scalar_type(py::object dtype) {\n    std::string dtype_str = py::str(dtype).cast<std::string>();\n\n    if (dtype_str == \"float32\") {\n        return ScalarType::Float32;\n    } else if (dtype_str == \"torch.float32\") {\n        return ScalarType::Float32;\n    } else if (dtype_str == \"float64\") {\n        return ScalarType::Float64;\n    } else if (dtype_str == \"torch.float64\") {\n        return ScalarType::Float64;\n    } else if (dtype_str == \"float16\") {\n        return ScalarType::Float16;\n    } else if (dtype_str == \"torch.float16\") {\n        return ScalarType::Float16;\n    } else {\n        throw std::runtime_error(\"unsupported dtype '\" + dtype_str + \"'\");\n    }\n}\n\ninline ScalarType dtype_to_scalar_type(at::ScalarType dtype) {\n    if (dtype == at::kFloat) {\n        return ScalarType::Float32;\n    } else if (dtype == at::kDouble) {\n        return ScalarType::Float64;\n    } else if (dtype == at::kHalf) {\n        return ScalarType::Float16;\n    } else {\n        throw std::runtime_error(\"unsupported dtype '\" +\n                                 std::string(c10::toString(dtype)) + \"'\");\n    }\n}\n\ninline caffe2::TypeMeta scalar_to_type_meta(ScalarType scalar) {\n    switch (scalar) {\n    case ScalarType::Float32:\n        return caffe2::TypeMeta::Make<float>();\n    case ScalarType::Float64:\n        return caffe2::TypeMeta::Make<double>();\n    case ScalarType::Float16:\n        return caffe2::TypeMeta::Make<at::Half>();\n    case ScalarType::UInt32:\n        return caffe2::TypeMeta::Make<uint32_t>();\n    default:\n        throw std::runtime_error(\"unsupported scalar type\");\n    }\n}\n\ninline std::array<uint32_t, 3> get_3d_shape(const torch::Tensor &tensor,\n                                            int feature_dims) {\n    std::array<uint32_t, 3> shape = {1, 1, 1};\n    uint32_t product = 1;\n    for (int i = 0; i < feature_dims; i++) {\n        product *= tensor.size(-(i + 1));\n    }\n    for (int i = 0; i < 2; i++) {\n        if (i + feature_dims + 1 > tensor.dim()) {\n            break;\n        }\n        product *= tensor.size(-(i + feature_dims + 1));\n        shape[i] = tensor.size(-(i + feature_dims + 1));\n    }\n    shape[2] = tensor.numel() / product;\n    return shape;\n}\n\n} // namespace radfoam_bindings"
  },
  {
    "path": "torch_bindings/pipeline_bindings.cpp",
    "content": "#include \"pipeline_bindings.h\"\n\n#include \"tracing/pipeline.h\"\n#include \"viewer/viewer.h\"\n\nnamespace radfoam_bindings {\n\nvoid validate_scene_data(const Pipeline &pipeline,\n                         torch::Tensor points,\n                         torch::Tensor attributes,\n                         torch::Tensor point_adjacency,\n                         torch::Tensor point_adjacency_offsets) {\n\n    if (points.size(-1) != 3) {\n        throw std::runtime_error(\"points had dimension \" +\n                                 std::to_string(points.size(-1)) +\n                                 \" along axis -1, expected 3\");\n    }\n    if (dtype_to_scalar_type(points.scalar_type()) != ScalarType::Float32) {\n        throw std::runtime_error(\n            \"points had dtype \" +\n            std::string(c10::toString(points.scalar_type())) + \", expected \" +\n            std::string(scalar_to_string(ScalarType::Float32)));\n    }\n    if (points.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"points must be on CUDA device\");\n    }\n    uint32_t num_points = points.numel() / 3;\n\n    if (attributes.size(-1) != pipeline.attribute_dim()) {\n        throw std::runtime_error(\"attributes had dimension \" +\n                                 std::to_string(attributes.size(-1)) +\n                                 \" along axis -1, expected \" +\n                                 std::to_string(pipeline.attribute_dim()));\n    }\n    if (attributes.numel() / pipeline.attribute_dim() != num_points) {\n        throw std::runtime_error(\"attributes must have the same number of \"\n                                 \"rows as points\");\n    }\n    if (dtype_to_scalar_type(attributes.scalar_type()) !=\n        pipeline.attribute_type()) {\n        throw std::runtime_error(\n            \"attributes had dtype \" +\n            std::string(c10::toString(attributes.scalar_type())) +\n            \", expected \" +\n            std::string(scalar_to_string(pipeline.attribute_type())));\n    }\n    if (attributes.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"attributes must be on CUDA device\");\n    }\n\n    if (point_adjacency_offsets.scalar_type() != at::kUInt32) {\n        throw std::runtime_error(\n            \"point_adjacency_offsets must have uint32 dtype\");\n    }\n    if (point_adjacency_offsets.device().type() != at::kCUDA) {\n        throw std::runtime_error(\n            \"point_adjacency_offsets must be on CUDA device\");\n    }\n    if (point_adjacency_offsets.numel() != num_points + 1) {\n        throw std::runtime_error(\"point_adjacency_offsets must have num_points \"\n                                 \"+ 1 elements\");\n    }\n\n    if (point_adjacency.scalar_type() != at::kUInt32) {\n        throw std::runtime_error(\"point_adjacency must have uint32 dtype\");\n    }\n    if (point_adjacency.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"point_adjacency must be on CUDA device\");\n    }\n}\n\nvoid update_scene(Viewer &self,\n                  torch::Tensor points_in,\n                  torch::Tensor attributes_in,\n                  torch::Tensor point_adjacency_in,\n                  torch::Tensor point_adjacency_offsets_in,\n                  torch::Tensor aabb_tree_in) {\n    torch::Tensor points = points_in.contiguous();\n    torch::Tensor attributes = attributes_in.contiguous();\n    torch::Tensor point_adjacency = point_adjacency_in.contiguous();\n    torch::Tensor point_adjacency_offsets =\n        point_adjacency_offsets_in.contiguous();\n    torch::Tensor aabb_tree = aabb_tree_in.contiguous();\n\n    validate_scene_data(self.get_pipeline(),\n                        points,\n                        attributes,\n                        point_adjacency,\n                        point_adjacency_offsets);\n\n    set_default_stream();\n\n    uint32_t num_points = points.size(0);\n    uint32_t num_attrs = attributes.size(0);\n    uint32_t num_point_adjacency = point_adjacency.size(0);\n    self.update_scene(num_points,\n                      num_attrs,\n                      num_point_adjacency,\n                      points.data_ptr(),\n                      attributes.data_ptr(),\n                      point_adjacency.data_ptr(),\n                      point_adjacency_offsets.data_ptr(),\n                      aabb_tree.data_ptr());\n}\n\npy::object trace_forward(Pipeline &self,\n                         torch::Tensor points_in,\n                         torch::Tensor attributes_in,\n                         torch::Tensor point_adjacency_in,\n                         torch::Tensor point_adjacency_offsets_in,\n                         torch::Tensor rays_in,\n                         torch::Tensor start_point_in,\n                         std::optional<torch::Tensor> depth_quantiles_in,\n                         py::object weight_threshold,\n                         py::object max_intersections,\n                         bool return_contribution) {\n    torch::Tensor points = points_in.contiguous();\n    torch::Tensor attributes = attributes_in.contiguous();\n    torch::Tensor point_adjacency = point_adjacency_in.contiguous();\n    torch::Tensor point_adjacency_offsets =\n        point_adjacency_offsets_in.contiguous();\n    torch::Tensor rays = rays_in.contiguous();\n    torch::Tensor start_point = start_point_in.contiguous();\n\n    validate_scene_data(self,\n                        points_in,\n                        attributes_in,\n                        point_adjacency_in,\n                        point_adjacency_offsets_in);\n\n    bool return_depth = depth_quantiles_in.has_value();\n\n    uint32_t num_points = points.size(0);\n    uint32_t point_adjacency_size = point_adjacency.size(0);\n    uint32_t num_rays = rays.numel() / 6;\n    uint32_t num_depth_quantiles = 0;\n\n    if (rays.size(-1) != 6) {\n        throw std::runtime_error(\"rays must have 6 as the last dimension\");\n    }\n    if (rays.scalar_type() != at::kFloat) {\n        throw std::runtime_error(\"rays must have float32 dtype\");\n    }\n    if (rays.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"rays must be on CUDA device\");\n    }\n\n    if (start_point.numel() != num_rays) {\n        throw std::runtime_error(\"start_point must have the same batch size \"\n                                 \"as rays\");\n    }\n    if (start_point.scalar_type() != at::kUInt32) {\n        throw std::runtime_error(\"start_point must have uint32 dtype\");\n    }\n    if (start_point.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"start_point must be on CUDA device\");\n    }\n\n    torch::Tensor depth_quantiles;\n    if (return_depth) {\n        depth_quantiles = depth_quantiles_in.value().contiguous();\n        num_depth_quantiles = depth_quantiles.size(-1);\n\n        if (depth_quantiles.scalar_type() != at::kFloat) {\n            throw std::runtime_error(\"depth_quantiles must have float32 dtype\");\n        }\n        if (depth_quantiles.device().type() != at::kCUDA) {\n            throw std::runtime_error(\"depth_quantiles must be on CUDA device\");\n        }\n        if (depth_quantiles.numel() / num_depth_quantiles != num_rays) {\n            throw std::runtime_error(\"depth_quantiles must have the same batch \"\n                                     \"size as rays\");\n        }\n    }\n\n    TraceSettings settings = default_trace_settings();\n    if (!weight_threshold.is_none()) {\n        settings.weight_threshold = weight_threshold.cast<float>();\n    }\n    if (!max_intersections.is_none()) {\n        settings.max_intersections = max_intersections.cast<uint32_t>();\n    }\n\n    std::vector<int64_t> output_shape;\n    for (int i = 0; i < rays.dim() - 1; i++) {\n        output_shape.push_back(rays.size(i));\n    }\n    auto output_rgba_shape = output_shape;\n    output_rgba_shape.push_back(4);\n    torch::Tensor output_rgba =\n        torch::empty(output_rgba_shape,\n                     torch::dtype(scalar_to_type_meta(self.attribute_type()))\n                         .device(rays.device()));\n\n    auto output_num_intersections_shape = output_shape;\n    output_num_intersections_shape.push_back(1);\n    torch::Tensor num_intersections =\n        torch::empty(output_num_intersections_shape,\n                     torch::dtype(scalar_to_type_meta(ScalarType::UInt32))\n                         .device(rays.device()));\n\n    torch::Tensor output_contribution;\n    if (return_contribution) {\n        output_contribution = torch::zeros(\n            {num_points, 1},\n            torch::dtype(scalar_to_type_meta(self.attribute_type()))\n                .device(rays.device()));\n    }\n\n    auto output_depth_shape = output_shape;\n    output_depth_shape.push_back(num_depth_quantiles);\n    torch::Tensor output_depth;\n    torch::Tensor output_depth_indices;\n    if (return_depth) {\n        output_depth =\n            torch::zeros(output_depth_shape,\n                         torch::dtype(scalar_to_type_meta(ScalarType::Float32))\n                             .device(rays.device()));\n        output_depth_indices =\n            torch::zeros(output_depth_shape,\n                         torch::dtype(scalar_to_type_meta(ScalarType::UInt32))\n                             .device(rays.device()));\n    }\n\n    set_default_stream();\n\n    self.trace_forward(\n        settings,\n        num_points,\n        reinterpret_cast<const radfoam::Vec3f *>(points.data_ptr()),\n        attributes.data_ptr(),\n        point_adjacency_size,\n        reinterpret_cast<const uint32_t *>(point_adjacency.data_ptr()),\n        reinterpret_cast<const uint32_t *>(point_adjacency_offsets.data_ptr()),\n        num_rays,\n        reinterpret_cast<const radfoam::Ray *>(rays.data_ptr()),\n        reinterpret_cast<const uint32_t *>(start_point.data_ptr()),\n        num_depth_quantiles,\n        return_depth\n            ? reinterpret_cast<const float *>(depth_quantiles.data_ptr())\n            : nullptr,\n        output_rgba.data_ptr(),\n        return_depth ? reinterpret_cast<float *>(output_depth.data_ptr())\n                     : nullptr,\n        return_depth\n            ? reinterpret_cast<uint32_t *>(output_depth_indices.data_ptr())\n            : nullptr,\n        reinterpret_cast<uint32_t *>(num_intersections.data_ptr()),\n        return_contribution ? output_contribution.data_ptr() : nullptr);\n\n    py::dict output_dict;\n\n    output_dict[\"rgba\"] = output_rgba;\n    if (return_depth) {\n        output_dict[\"depth\"] = output_depth;\n        output_dict[\"depth_indices\"] = output_depth_indices;\n    }\n    if (return_contribution) {\n        output_dict[\"contribution\"] = output_contribution;\n    }\n    output_dict[\"num_intersections\"] = num_intersections;\n\n    return output_dict;\n}\n\npy::object trace_backward(Pipeline &self,\n                          torch::Tensor points_in,\n                          torch::Tensor attributes_in,\n                          torch::Tensor point_adjacency_in,\n                          torch::Tensor point_adjacency_offsets_in,\n                          torch::Tensor rays_in,\n                          torch::Tensor start_point_in,\n                          torch::Tensor rgb_out,\n                          torch::Tensor rgb_grad_in,\n                          std::optional<torch::Tensor> depth_quantiles_in,\n                          std::optional<torch::Tensor> depth_indices_in,\n                          std::optional<torch::Tensor> depth_grad_in,\n                          std::optional<torch::Tensor> ray_error_in,\n                          py::object weight_threshold,\n                          py::object max_intersections) {\n    torch::Tensor points = points_in.contiguous();\n    torch::Tensor attributes = attributes_in.contiguous();\n    torch::Tensor point_adjacency = point_adjacency_in.contiguous();\n    torch::Tensor point_adjacency_offsets =\n        point_adjacency_offsets_in.contiguous();\n    torch::Tensor rays = rays_in.contiguous();\n    torch::Tensor start_point = start_point_in.contiguous();\n\n    validate_scene_data(self,\n                        points_in,\n                        attributes_in,\n                        point_adjacency_in,\n                        point_adjacency_offsets_in);\n\n    bool return_depth = depth_quantiles_in.has_value();\n    bool return_error = ray_error_in.has_value();\n\n    uint32_t num_points = points.size(0);\n    uint32_t point_adjacency_size = point_adjacency.size(0);\n    uint32_t num_rays = rays.numel() / 6;\n    uint32_t num_depth_quantiles = 0;\n\n    if (rays.size(-1) != 6) {\n        throw std::runtime_error(\"rays must have 6 as the last dimension\");\n    }\n    if (rays.scalar_type() != at::kFloat) {\n        throw std::runtime_error(\"rays must have float32 dtype\");\n    }\n    if (rays.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"rays must be on CUDA device\");\n    }\n\n    if (start_point.numel() != num_rays) {\n        throw std::runtime_error(\"start_point must have the same batch size \"\n                                 \"as rays\");\n    }\n    if (start_point.scalar_type() != at::kUInt32) {\n        throw std::runtime_error(\"start_point must have uint32 dtype\");\n    }\n    if (start_point.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"start_point must be on CUDA device\");\n    }\n\n    torch::Tensor rgb_grad_in_c = rgb_grad_in.contiguous();\n    if (rgb_grad_in_c.size(-1) != 4) {\n        throw std::runtime_error(\"rgb_grad_in must have 4 as \"\n                                 \"the last dimension\");\n    }\n    if (dtype_to_scalar_type(rgb_grad_in_c.scalar_type()) !=\n        self.attribute_type()) {\n        throw std::runtime_error(\n            \"rgb_grad_in had dtype \" +\n            std::string(c10::toString(rgb_grad_in_c.scalar_type())) +\n            \", expected \" +\n            std::string(scalar_to_string(self.attribute_type())));\n    }\n    if (rgb_grad_in_c.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"rgb_grad_in must be on CUDA device\");\n    }\n    if (rgb_grad_in_c.numel() / 4 != num_rays) {\n        throw std::runtime_error(\"rgb_grad_in must have the same batch size \"\n                                 \"as rays\");\n    }\n\n    torch::Tensor depth_quantiles;\n    torch::Tensor depth_indices;\n    torch::Tensor depth_grad;\n    if (return_depth) {\n        depth_quantiles = depth_quantiles_in.value().contiguous();\n        num_depth_quantiles = depth_quantiles.size(-1);\n\n        if (depth_quantiles.scalar_type() != at::kFloat) {\n            throw std::runtime_error(\"depth_quantiles must have float32 dtype\");\n        }\n        if (depth_quantiles.device().type() != at::kCUDA) {\n            throw std::runtime_error(\"depth_quantiles must be on CUDA device\");\n        }\n        if (depth_quantiles.numel() != num_rays * num_depth_quantiles) {\n            throw std::runtime_error(\"depth_quantiles must have the same batch \"\n                                     \"size as rays\");\n        }\n\n        if (!depth_grad_in.has_value()) {\n            throw std::runtime_error(\"depth_grad must be provided if \"\n                                     \"depth_quantiles is provided\");\n        }\n\n        depth_indices = depth_indices_in.value().contiguous();\n\n        if (depth_indices.scalar_type() != at::kUInt32) {\n            throw std::runtime_error(\"depth_indices must have uint32 dtype\");\n        }\n        if (depth_indices.device().type() != at::kCUDA) {\n            throw std::runtime_error(\"depth_indices must be on CUDA device\");\n        }\n        if (depth_indices.numel() != num_rays * num_depth_quantiles) {\n            throw std::runtime_error(\"depth_indices must have the same batch \"\n                                     \"size as rays\");\n        }\n\n        depth_grad = depth_grad_in.value().contiguous();\n\n        if (depth_grad.size(-1) != num_depth_quantiles) {\n            throw std::runtime_error(\"depth_grad must have the same number of \"\n                                     \"depth quantiles as depth_quantiles\");\n        }\n        if (dtype_to_scalar_type(depth_grad.scalar_type()) !=\n            ScalarType::Float32) {\n            throw std::runtime_error(\n                \"depth_grad had dtype \" +\n                std::string(c10::toString(depth_grad.scalar_type())) +\n                \", expected \" +\n                std::string(scalar_to_string(ScalarType::Float32)));\n        }\n        if (depth_grad.device().type() != at::kCUDA) {\n            throw std::runtime_error(\"depth_grad must be on CUDA device\");\n        }\n        if (depth_grad.numel() != num_rays * num_depth_quantiles) {\n            throw std::runtime_error(\"depth_grad must have the same batch \"\n                                     \"size as rays\");\n        }\n    }\n\n    torch::Tensor ray_error;\n    torch::Tensor point_error;\n    if (return_error) {\n        ray_error = ray_error_in.value().contiguous();\n\n        if (dtype_to_scalar_type(ray_error.scalar_type()) !=\n            self.attribute_type()) {\n            throw std::runtime_error(\n                \"ray_error had dtype \" +\n                std::string(c10::toString(ray_error.scalar_type())) +\n                \", expected \" +\n                std::string(scalar_to_string(self.attribute_type())));\n        }\n        if (ray_error.device().type() != at::kCUDA) {\n            throw std::runtime_error(\"ray_error must be on CUDA device\");\n        }\n        if (ray_error.numel() != num_rays) {\n            std::cout << ray_error.numel() << \" \" << num_rays << std::endl;\n            throw std::runtime_error(\"ray_error must have the same batch size \"\n                                     \"as rays\");\n        }\n\n        point_error = torch::zeros(\n            {num_points, 1},\n            torch::dtype(scalar_to_type_meta(self.attribute_type()))\n                .device(rays.device()));\n    }\n\n    TraceSettings settings = default_trace_settings();\n    if (!weight_threshold.is_none()) {\n        settings.weight_threshold = weight_threshold.cast<float>();\n    }\n    if (!max_intersections.is_none()) {\n        settings.max_intersections = max_intersections.cast<uint32_t>();\n    }\n\n    int64_t num_attr = attributes.size(0);\n\n    std::vector<int64_t> attr_grad_shape = {num_attr, self.attribute_dim()};\n\n    torch::Tensor attr_grad =\n        torch::zeros(attr_grad_shape,\n                     torch::dtype(scalar_to_type_meta(self.attribute_type()))\n                         .device(rays.device()));\n\n    std::vector<int64_t> points_grad_shape = {(int64_t)num_points, 3};\n\n    torch::Tensor points_grad = torch::zeros(\n        points_grad_shape, torch::dtype(rays.dtype()).device(rays.device()));\n\n    torch::Tensor ray_grad = torch::empty_like(rays);\n\n    set_default_stream();\n\n    self.trace_backward(\n        settings,\n        num_points,\n        reinterpret_cast<const radfoam::Vec3f *>(points.data_ptr()),\n        attributes.data_ptr(),\n        point_adjacency_size,\n        reinterpret_cast<const uint32_t *>(point_adjacency.data_ptr()),\n        reinterpret_cast<const uint32_t *>(point_adjacency_offsets.data_ptr()),\n        num_rays,\n        reinterpret_cast<const radfoam::Ray *>(rays.data_ptr()),\n        reinterpret_cast<const uint32_t *>(start_point.data_ptr()),\n        num_depth_quantiles,\n        return_depth\n            ? reinterpret_cast<const float *>(depth_quantiles.data_ptr())\n            : nullptr,\n        return_depth\n            ? reinterpret_cast<const uint32_t *>(depth_indices.data_ptr())\n            : nullptr,\n        rgb_out.data_ptr(),\n        rgb_grad_in_c.data_ptr(),\n        return_depth ? reinterpret_cast<const float *>(depth_grad.data_ptr())\n                     : nullptr,\n        return_error ? ray_error.data_ptr() : nullptr,\n        reinterpret_cast<radfoam::Ray *>(ray_grad.data_ptr()),\n        reinterpret_cast<radfoam::Vec3f *>(points_grad.data_ptr()),\n        attr_grad.data_ptr(),\n        return_error ? point_error.data_ptr() : nullptr);\n\n    py::dict output_dict;\n\n    output_dict[\"points_grad\"] = points_grad;\n    output_dict[\"attr_grad\"] = attr_grad;\n    output_dict[\"ray_grad\"] = ray_grad;\n    if (return_error) {\n        output_dict[\"point_error\"] = point_error;\n    }\n\n    return output_dict;\n}\n\nvoid trace_benchmark(Pipeline &self,\n                     torch::Tensor points_in,\n                     torch::Tensor attributes_in,\n                     torch::Tensor point_adjacency_in,\n                     torch::Tensor point_adjacency_offsets_in,\n                     torch::Tensor adjacent_diff_in,\n                     py::dict camera_in,\n                     torch::Tensor start_point,\n                     torch::Tensor output_rgba_in,\n                     py::object weight_threshold,\n                     py::object max_intersections) {\n    torch::Tensor points = points_in.contiguous();\n    torch::Tensor attributes = attributes_in.contiguous();\n    torch::Tensor point_adjacency = point_adjacency_in.contiguous();\n    torch::Tensor point_adjacency_offsets =\n        point_adjacency_offsets_in.contiguous();\n    torch::Tensor adjacent_diff = adjacent_diff_in.contiguous();\n\n    validate_scene_data(self,\n                        points_in,\n                        attributes_in,\n                        point_adjacency_in,\n                        point_adjacency_offsets_in);\n\n    uint32_t num_points = points.size(0);\n\n    radfoam::Camera camera;\n    camera.position = radfoam::Vec3f(\n        camera_in[\"position\"].cast<torch::Tensor>().data_ptr<float>());\n    camera.forward = radfoam::Vec3f(\n        camera_in[\"forward\"].cast<torch::Tensor>().data_ptr<float>());\n    camera.up =\n        radfoam::Vec3f(camera_in[\"up\"].cast<torch::Tensor>().data_ptr<float>());\n    camera.right = radfoam::Vec3f(\n        camera_in[\"right\"].cast<torch::Tensor>().data_ptr<float>());\n    camera.fov = camera_in[\"fov\"].cast<float>();\n    camera.width = camera_in[\"width\"].cast<int>();\n    camera.height = camera_in[\"height\"].cast<int>();\n    if (camera_in[\"model\"].cast<std::string>() == \"pinhole\") {\n        camera.model = radfoam::CameraModel::Pinhole;\n    } else if (camera_in[\"model\"].cast<std::string>() == \"fisheye\") {\n        camera.model = radfoam::CameraModel::Fisheye;\n    } else {\n        throw std::runtime_error(\"Invalid camera model\");\n    }\n\n    if (start_point.numel() != 1) {\n        throw std::runtime_error(\"start_point must have a single element\");\n    }\n    if (start_point.scalar_type() != at::kUInt32) {\n        throw std::runtime_error(\"start_point must have uint32 dtype\");\n    }\n    if (start_point.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"start_point must be on CUDA device\");\n    }\n\n    if (output_rgba_in.numel() != camera.width * camera.height) {\n        throw std::runtime_error(\"output_rgba must have width * height \"\n                                 \"elements\");\n    }\n    if (output_rgba_in.scalar_type() != at::kUInt32) {\n        throw std::runtime_error(\"output_rgba must have uint32 dtype\");\n    }\n    if (output_rgba_in.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"output_rgba must be on CUDA device\");\n    }\n\n    TraceSettings settings = default_trace_settings();\n    if (!weight_threshold.is_none()) {\n        settings.weight_threshold = weight_threshold.cast<float>();\n    }\n    if (!max_intersections.is_none()) {\n        settings.max_intersections = max_intersections.cast<uint32_t>();\n    }\n\n    self.trace_benchmark(\n        settings,\n        num_points,\n        reinterpret_cast<const radfoam::Vec3f *>(points.data_ptr()),\n        attributes.data_ptr(),\n        reinterpret_cast<const uint32_t *>(point_adjacency.data_ptr()),\n        reinterpret_cast<const uint32_t *>(point_adjacency_offsets.data_ptr()),\n        reinterpret_cast<const radfoam::Vec4h *>(adjacent_diff.data_ptr()),\n        camera,\n        reinterpret_cast<const uint32_t *>(start_point.data_ptr()),\n        reinterpret_cast<uint32_t *>(output_rgba_in.data_ptr()));\n}\n\nstd::shared_ptr<Pipeline> create_pipeline(int sh_degree,\n                                          py::object attr_dtype) {\n    return create_pipeline(sh_degree, dtype_to_scalar_type(attr_dtype));\n}\n\nvoid run_with_viewer(std::shared_ptr<Pipeline> pipeline,\n                     std::function<void(std::shared_ptr<Viewer>)> callback,\n                     std::optional<int> total_iterations,\n                     std::optional<torch::Tensor> camera_pos,\n                     std::optional<torch::Tensor> camera_forward,\n                     std::optional<torch::Tensor> camera_up) {\n    py::gil_scoped_release release;\n\n    ViewerOptions options = default_viewer_options();\n    if (total_iterations.has_value()) {\n        options.total_iterations = total_iterations.value();\n    }\n    if (camera_pos.has_value()) {\n        torch::Tensor camera_pos_cpu =\n            camera_pos->contiguous().cpu().to(torch::kFloat);\n        options.camera_pos = radfoam::Vec3f(camera_pos_cpu.data_ptr<float>());\n    }\n    if (camera_forward.has_value()) {\n        torch::Tensor camera_forward_cpu =\n            camera_forward->contiguous().cpu().to(torch::kFloat);\n        options.camera_forward =\n            radfoam::Vec3f(camera_forward_cpu.data_ptr<float>());\n    }\n    if (camera_up.has_value()) {\n        torch::Tensor camera_up_cpu =\n            camera_up->contiguous().cpu().to(torch::kFloat);\n        options.camera_up = radfoam::Vec3f(camera_up_cpu.data_ptr<float>());\n    }\n\n    set_default_stream();\n\n    run_with_viewer(std::move(pipeline), std::move(callback), options);\n}\n\nvoid init_pipeline_bindings(py::module &module) {\n    py::class_<Pipeline, std::shared_ptr<Pipeline>>(module, \"Pipeline\")\n        .def(\"trace_forward\",\n             trace_forward,\n             py::arg(\"points\"),\n             py::arg(\"attributes\"),\n             py::arg(\"point_adjacency\"),\n             py::arg(\"point_adjacency_offsets\"),\n             py::arg(\"rays\"),\n             py::arg(\"start_point\"),\n             py::arg(\"depth_quantiles\") = py::none(),\n             py::arg(\"weight_threshold\") = py::none(),\n             py::arg(\"max_intersections\") = py::none(),\n             py::arg(\"return_contribution\") = false)\n        .def(\"trace_backward\",\n             trace_backward,\n             py::arg(\"points\"),\n             py::arg(\"attributes\"),\n             py::arg(\"point_adjacency\"),\n             py::arg(\"point_adjacency_offsets\"),\n             py::arg(\"rays\"),\n             py::arg(\"start_point\"),\n             py::arg(\"rgb_out\"),\n             py::arg(\"grad_in\"),\n             py::arg(\"depth_quantiles\") = py::none(),\n             py::arg(\"depth_indices\") = py::none(),\n             py::arg(\"depth_grad_in\") = py::none(),\n             py::arg(\"ray_error\") = py::none(),\n             py::arg(\"weight_threshold\") = py::none(),\n             py::arg(\"max_intersections\") = py::none())\n        .def(\"trace_benchmark\",\n             trace_benchmark,\n             py::arg(\"points\"),\n             py::arg(\"attributes\"),\n             py::arg(\"point_adjacency\"),\n             py::arg(\"point_adjacency_offsets\"),\n             py::arg(\"adjacent_diff\"),\n             py::arg(\"camera\"),\n             py::arg(\"start_point\"),\n             py::arg(\"output_rgba\"),\n             py::arg(\"weight_threshold\") = py::none(),\n             py::arg(\"max_intersections\") = py::none());\n\n    module.def(\"create_pipeline\",\n               create_pipeline,\n               py::arg(\"sh_degree\"),\n               py::arg(\"attr_dtype\") = \"float32\");\n\n    py::class_<Viewer, std::shared_ptr<Viewer>>(module, \"Viewer\")\n        .def(\"update_scene\",\n             update_scene,\n             py::arg(\"points\"),\n             py::arg(\"attributes\"),\n             py::arg(\"point_adjacency\"),\n             py::arg(\"point_adjacency_offsets\"),\n             py::arg(\"aabb_tree\"))\n        .def(\"step\", &Viewer::step)\n        .def(\"is_closed\", &Viewer::is_closed);\n\n    module.def(\"run_with_viewer\",\n               run_with_viewer,\n               py::arg(\"pipeline\"),\n               py::arg(\"callback\"),\n               py::arg(\"total_iterations\") = py::none(),\n               py::arg(\"camera_pos\") = py::none(),\n               py::arg(\"camera_forward\") = py::none(),\n               py::arg(\"camera_up\") = py::none());\n}\n\n} // namespace radfoam_bindings"
  },
  {
    "path": "torch_bindings/pipeline_bindings.h",
    "content": "#pragma once\n\n#include \"bindings.h\"\n\nnamespace radfoam_bindings {\n\nvoid init_pipeline_bindings(py::module &module);\n\n}"
  },
  {
    "path": "torch_bindings/radfoam/__init__.py.in",
    "content": "import os\nimport warnings\nimport ctypes\n\nimport torch\n\ntorch_version_at_compile = \"@TORCH_VERSION@\"\ntorch_version_at_runtime = torch.__version__.split(\"+\")[0]\n\nif torch_version_at_compile != torch_version_at_runtime:\n    warnings.warn(\n        f\"RadFoam was compiled with torch version {torch_version_at_compile}, but \"\n        f\"the current torch version is {torch_version_at_runtime}. This might lead to \"\n        \"unexpected behavior or crashes.\"\n    )\n\nif @USE_PIP_GLFW@:\n    import glfw\n    glfw_path = os.path.split(glfw.__file__)[0]\n    libglfw_path = os.path.join(glfw_path, \"x11\", \"libglfw.so\")\n    libdl = ctypes.CDLL(\"libdl.so.2\")\n    RTLD_NOW = 0x00002\n    RTLD_GLOBAL = 0x00100\n    handle = libdl.dlopen(libglfw_path.encode(\"utf-8\"), RTLD_NOW | RTLD_GLOBAL)\n\n    if handle is None:\n        raise ImportError(\"failed to load libglfw.so\")\n\nfrom .torch_bindings import *\n"
  },
  {
    "path": "torch_bindings/torch_bindings.cpp",
    "content": "\n#include <optional>\n#include <stdexcept>\n#include <tuple>\n#include <vector>\n\n#include \"pipeline_bindings.h\"\n#include \"triangulation_bindings.h\"\n#include \"utils/batch_fetcher.h\"\n#include \"utils/cuda_array.h\"\n\nnamespace radfoam {\n\nstruct TorchBuffer : public OpaqueBuffer {\n    torch::Tensor tensor;\n\n    TorchBuffer(size_t bytes) {\n        // allocate on CUDA device\n        // int64 dtype for alignment\n        size_t num_words = (bytes + sizeof(int64_t) - 1) / sizeof(int64_t);\n        tensor = torch::empty({(int64_t)num_words},\n                              torch::dtype(torch::kInt64).device(torch::kCUDA));\n    }\n\n    void *data() override { return tensor.data_ptr(); }\n};\n\nstd::unique_ptr<OpaqueBuffer> allocate_buffer(size_t bytes) {\n    return std::make_unique<TorchBuffer>(bytes);\n}\n\nstruct TorchBatchFetcher {\n    std::unique_ptr<BatchFetcher> fetcher;\n    torch::Tensor data;\n    size_t batch_size;\n\n    TorchBatchFetcher(torch::Tensor _data, size_t _batch_size, bool shuffle)\n        : data(_data), batch_size(_batch_size) {\n        size_t num_bytes = data.numel() * data.element_size();\n        size_t num_elems = data.size(0);\n        size_t stride = num_bytes / num_elems;\n        fetcher = create_batch_fetcher(\n            data.data_ptr(), num_bytes, stride, batch_size, shuffle);\n    }\n\n    torch::Tensor next() {\n        void *batch = fetcher->next();\n        std::vector<int64_t> shape;\n        shape.push_back(batch_size);\n        for (int i = 1; i < data.dim(); i++) {\n            shape.push_back(data.size(i));\n        }\n        return torch::from_blob(batch,\n                                shape,\n                                torch::dtype(data.dtype()).device(torch::kCUDA))\n            .clone();\n    }\n};\n\nstd::unique_ptr<TorchBatchFetcher> create_torch_batch_fetcher(\n    torch::Tensor data, size_t batch_size, bool shuffle) {\n    return std::make_unique<TorchBatchFetcher>(data, batch_size, shuffle);\n}\n\n} // namespace radfoam\n\nnamespace radfoam_bindings {\n\nPYBIND11_MODULE(torch_bindings, module) {\n    using namespace radfoam_bindings;\n\n    module.doc() = \"radfoam pytorch bindings module\";\n\n    init_pipeline_bindings(module);\n    init_triangulation_bindings(module);\n\n    py::class_<TorchBatchFetcher, std::unique_ptr<TorchBatchFetcher>>(\n        module, \"BatchFetcher\")\n        .def(py::init(&create_torch_batch_fetcher),\n             py::arg(\"data\"),\n             py::arg(\"batch_size\"),\n             py::arg(\"shuffle\"))\n        .def(\"next\", &TorchBatchFetcher::next);\n}\n\n} // namespace radfoam_bindings\n"
  },
  {
    "path": "torch_bindings/triangulation_bindings.cpp",
    "content": "#include <memory>\n\n#include \"triangulation_bindings.h\"\n\n#include \"aabb_tree/aabb_tree.h\"\n#include \"delaunay/delaunay.h\"\n#include \"delaunay/triangulation_ops.h\"\n\nnamespace radfoam_bindings {\n\nstd::unique_ptr<Triangulation> create_triangulation(torch::Tensor points) {\n    if (points.size(-1) != 3) {\n        throw std::runtime_error(\"points must have 3 as the last dimension\");\n    }\n    if (points.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"points must be on CUDA device\");\n    }\n    if (points.scalar_type() != torch::kFloat32) {\n        throw std::runtime_error(\"points must have float32 dtype\");\n    }\n\n    uint32_t num_points = points.numel() / 3;\n\n    set_default_stream();\n\n    return Triangulation::create_triangulation(points.data_ptr(), num_points);\n}\n\nbool rebuild(Triangulation &triangulation,\n             torch::Tensor points,\n             bool incremental) {\n    if (points.size(-1) != 3) {\n        throw std::runtime_error(\"points must have 3 as the last dimension\");\n    }\n    if (points.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"points must be on CUDA device\");\n    }\n    if (points.scalar_type() != torch::kFloat32) {\n        throw std::runtime_error(\"points must have float32 dtype\");\n    }\n\n    set_default_stream();\n\n    return triangulation.rebuild(\n        points.data_ptr(), points.numel() / 3, incremental);\n}\n\ntorch::Tensor permutation(const Triangulation &triangulation) {\n    const uint32_t *permutation = triangulation.permutation();\n    uint32_t num_points = triangulation.num_points();\n\n    at::TensorOptions options =\n        at::TensorOptions().dtype(torch::kUInt32).device(torch::kCUDA);\n\n    return torch::from_blob(\n        const_cast<uint32_t *>(permutation), {num_points}, options);\n}\n\ntorch::Tensor get_tets(const Triangulation &triangulation) {\n    const IndexedTet *tets = triangulation.tets();\n    uint32_t num_tets = triangulation.num_tets();\n\n    at::TensorOptions options =\n        at::TensorOptions().dtype(torch::kUInt32).device(torch::kCUDA);\n\n    return torch::from_blob(\n        const_cast<IndexedTet *>(tets), {num_tets, 4}, options);\n}\n\ntorch::Tensor get_tet_adjacency(const Triangulation &triangulation) {\n    const uint32_t *tet_adjacency = triangulation.tet_adjacency();\n    uint32_t num_tets = triangulation.num_tets();\n\n    at::TensorOptions options =\n        at::TensorOptions().dtype(torch::kUInt32).device(torch::kCUDA);\n\n    return torch::from_blob(\n        const_cast<uint32_t *>(tet_adjacency), {num_tets, 4}, options);\n}\n\ntorch::Tensor get_point_adjacency(const Triangulation &triangulation) {\n    const uint32_t *point_adjacency = triangulation.point_adjacency();\n    uint32_t point_adjacency_size = triangulation.point_adjacency_size();\n\n    at::TensorOptions options =\n        at::TensorOptions().dtype(torch::kUInt32).device(torch::kCUDA);\n\n    return torch::from_blob(const_cast<uint32_t *>(point_adjacency),\n                            {point_adjacency_size},\n                            options);\n}\n\ntorch::Tensor get_point_adjacency_offsets(const Triangulation &triangulation) {\n    const uint32_t *point_adjacency_offsets =\n        triangulation.point_adjacency_offsets();\n    uint32_t num_points = triangulation.num_points();\n\n    at::TensorOptions options =\n        at::TensorOptions().dtype(torch::kUInt32).device(torch::kCUDA);\n\n    return torch::from_blob(const_cast<uint32_t *>(point_adjacency_offsets),\n                            {num_points + 1},\n                            options);\n}\n\ntorch::Tensor get_vert_to_tet(const Triangulation &triangulation) {\n    const uint32_t *vert_to_tet = triangulation.vert_to_tet();\n    uint32_t num_points = triangulation.num_points();\n\n    at::TensorOptions options =\n        at::TensorOptions().dtype(torch::kUInt32).device(torch::kCUDA);\n\n    return torch::from_blob(\n        const_cast<uint32_t *>(vert_to_tet), {num_points}, options);\n}\n\ntorch::Tensor build_aabb_tree(torch::Tensor points) {\n    if (points.size(-1) != 3) {\n        throw std::runtime_error(\"points must have 3 as the last dimension\");\n    }\n    if (points.dim() != 2) {\n        throw std::runtime_error(\"points must have 2 dimensions\");\n    }\n    if (points.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"points must be on CUDA device\");\n    }\n\n    ScalarType scalar_type = dtype_to_scalar_type(points.scalar_type());\n\n    uint32_t num_points = points.numel() / 3;\n\n    torch::Tensor aabb_tree = torch::empty(\n        {pow2_round_up(num_points), 2, 3},\n        torch::TensorOptions().dtype(points.dtype()).device(points.device()));\n\n    radfoam::build_aabb_tree(\n        scalar_type, points.data_ptr(), num_points, aabb_tree.data_ptr());\n\n    return aabb_tree;\n}\n\ntorch::Tensor\nnn(torch::Tensor points, torch::Tensor tree, torch::Tensor queries) {\n    uint32_t num_points = points.numel() / 3;\n    uint32_t num_queries = queries.numel() / 3;\n\n    if (points.scalar_type() != queries.scalar_type()) {\n        throw std::runtime_error(\"points and queries must have the same dtype\");\n    }\n    if (points.scalar_type() != tree.scalar_type()) {\n        throw std::runtime_error(\"points and tree must have the same dtype\");\n    }\n    if (points.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"points must be on CUDA device\");\n    }\n    if (tree.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"tree must be on CUDA device\");\n    }\n    if (queries.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"queries must be on CUDA device\");\n    }\n\n    std::vector<int64_t> indices_shape;\n\n    for (int64_t i = 0; i < queries.dim() - 1; i++) {\n        indices_shape.push_back(queries.size(i));\n    }\n\n    torch::Tensor indices = torch::zeros(\n        indices_shape, torch::dtype(torch::kUInt32).device(queries.device()));\n\n    radfoam::nn(dtype_to_scalar_type(points.scalar_type()),\n                points.data_ptr(),\n                tree.data_ptr(),\n                queries.data_ptr(),\n                num_points,\n                num_queries,\n                static_cast<uint32_t *>(indices.data_ptr()));\n\n    return indices;\n}\n\nstd::tuple<torch::Tensor, torch::Tensor>\nfarthest_neighbor(torch::Tensor points_in,\n                  torch::Tensor point_adjacency_in,\n                  torch::Tensor point_adjacency_offsets_in) {\n    uint32_t num_points = points_in.size(0);\n    torch::Tensor points = points_in.contiguous();\n    torch::Tensor point_adjacency = point_adjacency_in.contiguous();\n    torch::Tensor point_adjacency_offsets =\n        point_adjacency_offsets_in.contiguous();\n\n    if (points.device().type() != at::kCUDA) {\n        throw std::runtime_error(\"points must be on CUDA device\");\n    }\n\n    std::vector<int64_t> indices_shape;\n\n    for (int64_t i = 0; i < points.dim() - 1; i++) {\n        indices_shape.push_back(points.size(i));\n    }\n\n    torch::Tensor indices = torch::zeros(\n        indices_shape, torch::dtype(torch::kUInt32).device(points.device()));\n    torch::Tensor cell_radius = torch::zeros(\n        indices_shape, torch::dtype(torch::kFloat32).device(points.device()));\n\n    radfoam::farthest_neighbor(dtype_to_scalar_type(points.scalar_type()),\n                               points.data_ptr(),\n                               point_adjacency.data_ptr(),\n                               point_adjacency_offsets.data_ptr(),\n                               num_points,\n                               static_cast<uint32_t *>(indices.data_ptr()),\n                               static_cast<float *>(cell_radius.data_ptr()));\n\n    return std::make_tuple(indices, cell_radius);\n}\n\nvoid init_triangulation_bindings(py::module &module) {\n    radfoam::global_cuda_init();\n\n    py::register_exception<radfoam::TriangulationFailedError>(\n        module, \"TriangulationFailedError\");\n\n    py::class_<Triangulation, std::unique_ptr<Triangulation>>(module,\n                                                              \"Triangulation\")\n        .def(py::init(&create_triangulation), py::arg(\"points\"))\n        .def(\"tets\", &get_tets)\n        .def(\"tet_adjacency\", &get_tet_adjacency)\n        .def(\"point_adjacency\", &get_point_adjacency)\n        .def(\"point_adjacency_offsets\", &get_point_adjacency_offsets)\n        .def(\"vert_to_tet\", &get_vert_to_tet)\n        .def(\"rebuild\",\n             &rebuild,\n             py::arg(\"points\"),\n             py::arg(\"incremental\") = false)\n        .def(\"permutation\", &permutation);\n\n    module.def(\"build_aabb_tree\", &build_aabb_tree, py::arg(\"points\"));\n\n    module.def(\n        \"nn\", &nn, py::arg(\"points\"), py::arg(\"tree\"), py::arg(\"queries\"));\n\n    module.def(\"farthest_neighbor\",\n               &farthest_neighbor,\n               py::arg(\"points\"),\n               py::arg(\"point_adjacency\"),\n               py::arg(\"point_adjacency_offsets\"));\n}\n\n} // namespace radfoam_bindings"
  },
  {
    "path": "torch_bindings/triangulation_bindings.h",
    "content": "#pragma once\n\n#include \"bindings.h\"\n\nnamespace radfoam_bindings {\n\nvoid init_triangulation_bindings(py::module &module);\n\n}"
  },
  {
    "path": "train.py",
    "content": "import os\nimport uuid\nimport yaml\nimport gc\nimport numpy as np\nfrom PIL import Image\nimport configargparse\nimport tqdm\nimport warnings\n\nwarnings.filterwarnings(\"ignore\")\n\nimport torch\nfrom torch import nn\nfrom torch.utils.tensorboard import SummaryWriter\n\nfrom data_loader import DataHandler\nfrom configs import *\nfrom radfoam_model.scene import RadFoamScene\nfrom radfoam_model.utils import psnr\nimport radfoam\n\n\nseed = 42\ntorch.random.manual_seed(seed)\nnp.random.seed(seed)\n\n\ndef train(args, pipeline_args, model_args, optimizer_args, dataset_args):\n    device = torch.device(model_args.device)\n    # Setting up output directory\n    if not pipeline_args.debug:\n        if len(pipeline_args.experiment_name) == 0:\n            unique_str = str(uuid.uuid4())[:8]\n            experiment_name = f\"{dataset_args.scene}@{unique_str}\"\n        else:\n            experiment_name = pipeline_args.experiment_name\n        out_dir = f\"output/{experiment_name}\"\n        writer = SummaryWriter(out_dir, purge_step=0)\n        os.makedirs(f\"{out_dir}/test\", exist_ok=True)\n\n        def represent_list_inline(dumper, data):\n            return dumper.represent_sequence(\n                \"tag:yaml.org,2002:seq\", data, flow_style=True\n            )\n\n        yaml.add_representer(list, represent_list_inline)\n\n        # Save the arguments to a YAML file\n        with open(f\"{out_dir}/config.yaml\", \"w\") as yaml_file:\n            yaml.dump(vars(args), yaml_file, default_flow_style=False)\n\n    # Setting up dataset\n    iter2downsample = dict(\n        zip(\n            dataset_args.downsample_iterations,\n            dataset_args.downsample,\n        )\n    )\n    train_data_handler = DataHandler(\n        dataset_args, rays_per_batch=1_000_000, device=device\n    )\n    downsample = iter2downsample[0]\n    train_data_handler.reload(split=\"train\", downsample=downsample)\n\n    test_data_handler = DataHandler(\n        dataset_args, rays_per_batch=0, device=device\n    )\n    test_data_handler.reload(\n        split=\"test\", downsample=min(dataset_args.downsample)\n    )\n    test_ray_batch_fetcher = radfoam.BatchFetcher(\n        test_data_handler.rays, batch_size=1, shuffle=False\n    )\n    test_rgb_batch_fetcher = radfoam.BatchFetcher(\n        test_data_handler.rgbs, batch_size=1, shuffle=False\n    )\n\n    # Define viewer settings\n    viewer_options = {\n        \"camera_pos\": train_data_handler.viewer_pos,\n        \"camera_up\": train_data_handler.viewer_up,\n        \"camera_forward\": train_data_handler.viewer_forward,\n    }\n\n    # Setting up pipeline\n    rgb_loss = nn.SmoothL1Loss(reduction=\"none\")\n\n    # Setting up model\n    model = RadFoamScene(\n        args=model_args,\n        device=device,\n        points=train_data_handler.points3D,\n        points_colors=train_data_handler.points3D_colors,\n    )\n\n    # Setting up optimizer\n    model.declare_optimizer(\n        args=optimizer_args,\n        warmup=pipeline_args.densify_from,\n        max_iterations=pipeline_args.iterations,\n    )\n\n    def test_render(\n        test_data_handler, ray_batch_fetcher, rgb_batch_fetcher, debug=False\n    ):\n        rays = test_data_handler.rays\n        points, _, _, _ = model.get_trace_data()\n        start_points = model.get_starting_point(\n            rays[:, 0, 0].cuda(), points, model.aabb_tree\n        )\n\n        psnr_list = []\n        with torch.no_grad():\n            for i in range(rays.shape[0]):\n                ray_batch = ray_batch_fetcher.next()[0]\n                rgb_batch = rgb_batch_fetcher.next()[0]\n                output, _, _, _, _ = model(ray_batch, start_points[i])\n\n                # White background\n                opacity = output[..., -1:]\n                rgb_output = output[..., :3] + (1 - opacity)\n                rgb_output = rgb_output.reshape(*rgb_batch.shape).clip(0, 1)\n\n                img_psnr = psnr(rgb_output, rgb_batch).mean()\n                psnr_list.append(img_psnr)\n                torch.cuda.synchronize()\n\n                if not debug:\n                    error = np.uint8((rgb_output - rgb_batch).cpu().abs() * 255)\n                    rgb_output = np.uint8(rgb_output.cpu() * 255)\n                    rgb_batch = np.uint8(rgb_batch.cpu() * 255)\n\n                    im = Image.fromarray(\n                        np.concatenate([rgb_output, rgb_batch, error], axis=1)\n                    )\n                    im.save(\n                        f\"{out_dir}/test/rgb_{i:03d}_psnr_{img_psnr:.3f}.png\"\n                    )\n\n        average_psnr = sum(psnr_list) / len(psnr_list)\n        if not debug:\n            f = open(f\"{out_dir}/metrics.txt\", \"w\")\n            f.write(f\"Average PSNR: {average_psnr}\")\n            f.close()\n\n        return average_psnr\n\n    def train_loop(viewer):\n        print(\"Training\")\n\n        torch.cuda.synchronize()\n\n        data_iterator = train_data_handler.get_iter()\n        ray_batch, rgb_batch, alpha_batch = next(data_iterator)\n\n        triangulation_update_period = 1\n        iters_since_update = 1\n        iters_since_densification = 0\n        next_densification_after = 1\n\n        with tqdm.trange(pipeline_args.iterations) as train:\n            for i in train:\n                if viewer is not None:\n                    model.update_viewer(viewer)\n                    viewer.step(i)\n\n                if i in iter2downsample and i:\n                    downsample = iter2downsample[i]\n                    train_data_handler.reload(\n                        split=\"train\", downsample=downsample\n                    )\n                    data_iterator = train_data_handler.get_iter()\n                    ray_batch, rgb_batch, alpha_batch = next(data_iterator)\n\n                depth_quantiles = (\n                    torch.rand(*ray_batch.shape[:-1], 2, device=device)\n                    .sort(dim=-1, descending=True)\n                    .values\n                )\n\n                rgba_output, depth, _, _, _ = model(\n                    ray_batch,\n                    depth_quantiles=depth_quantiles,\n                )\n\n                # White background\n                opacity = rgba_output[..., -1:]\n                if pipeline_args.white_background:\n                    rgb_output = rgba_output[..., :3] + (1 - opacity)\n                else:\n                    rgb_output = rgba_output[..., :3]\n\n                color_loss = rgb_loss(rgb_batch, rgb_output)\n                opacity_loss = ((alpha_batch - opacity) ** 2).mean()\n\n                valid_depth_mask = (depth > 0).all(dim=-1)\n                quant_loss = (depth[..., 0] - depth[..., 1]).abs()\n                quant_loss = (quant_loss * valid_depth_mask).mean()\n                w_depth = pipeline_args.quantile_weight * min(\n                    2 * i / pipeline_args.iterations, 1\n                )\n\n                loss = color_loss.mean() + opacity_loss + w_depth * quant_loss\n\n                model.optimizer.zero_grad(set_to_none=True)\n\n                # Hide latency of data loading behind the backward pass\n                event = torch.cuda.Event()\n                event.record()\n                loss.backward()\n                event.synchronize()\n                ray_batch, rgb_batch, alpha_batch = next(data_iterator)\n\n                model.optimizer.step()\n                model.update_learning_rate(i)\n\n                train.set_postfix(color_loss=f\"{color_loss.mean().item():.5f}\")\n\n                if i % 100 == 99 and not pipeline_args.debug:\n                    writer.add_scalar(\"train/rgb_loss\", color_loss.mean(), i)\n                    num_points = model.primal_points.shape[0]\n                    writer.add_scalar(\"test/num_points\", num_points, i)\n\n                    test_psnr = test_render(\n                        test_data_handler,\n                        test_ray_batch_fetcher,\n                        test_rgb_batch_fetcher,\n                        True,\n                    )\n                    writer.add_scalar(\"test/psnr\", test_psnr, i)\n\n                    writer.add_scalar(\n                        \"lr/points_lr\", model.xyz_scheduler_args(i), i\n                    )\n                    writer.add_scalar(\n                        \"lr/density_lr\", model.den_scheduler_args(i), i\n                    )\n                    writer.add_scalar(\n                        \"lr/attr_lr\", model.attr_dc_scheduler_args(i), i\n                    )\n\n                if iters_since_update >= triangulation_update_period:\n                    model.update_triangulation(incremental=True)\n                    iters_since_update = 0\n\n                    if triangulation_update_period < 100:\n                        triangulation_update_period += 2\n\n                iters_since_update += 1\n                if i + 1 >= pipeline_args.densify_from:\n                    iters_since_densification += 1\n\n                if (\n                    iters_since_densification == next_densification_after\n                    and model.primal_points.shape[0]\n                    < 0.9 * model.num_final_points\n                ):\n                    point_error, point_contribution = model.collect_error_map(\n                        train_data_handler, pipeline_args.white_background\n                    )\n                    model.prune_and_densify(\n                        point_error,\n                        point_contribution,\n                        pipeline_args.densify_factor,\n                    )\n\n                    model.update_triangulation(incremental=False)\n                    triangulation_update_period = 1\n                    gc.collect()\n\n                    # Linear growth\n                    iters_since_densification = 0\n                    next_densification_after = int(\n                        (\n                            (pipeline_args.densify_factor - 1)\n                            * model.primal_points.shape[0]\n                            * (\n                                pipeline_args.densify_until\n                                - pipeline_args.densify_from\n                            )\n                        )\n                        / (model.num_final_points - model.num_init_points)\n                    )\n                    next_densification_after = max(\n                        next_densification_after, 100\n                    )\n\n                if i == optimizer_args.freeze_points:\n                    model.update_triangulation(incremental=False)\n\n                if viewer is not None and viewer.is_closed():\n                    break\n\n        model.save_ply(f\"{out_dir}/scene.ply\")\n        model.save_pt(f\"{out_dir}/model.pt\")\n        del data_iterator\n\n    if pipeline_args.viewer:\n        model.show(\n            train_loop, iterations=pipeline_args.iterations, **viewer_options\n        )\n    else:\n        train_loop(viewer=None)\n    if not pipeline_args.debug:\n        writer.close()\n\n    test_render(\n        test_data_handler,\n        test_ray_batch_fetcher,\n        test_rgb_batch_fetcher,\n        pipeline_args.debug,\n    )\n\n\ndef main():\n    parser = configargparse.ArgParser(\n        default_config_files=[\"arguments/mipnerf360_outdoor_config.yaml\"]\n    )\n\n    model_params = ModelParams(parser)\n    pipeline_params = PipelineParams(parser)\n    optimization_params = OptimizationParams(parser)\n    dataset_params = DatasetParams(parser)\n\n    # Add argument to specify a custom config file\n    parser.add_argument(\n        \"-c\", \"--config\", is_config_file=True, help=\"Path to config file\"\n    )\n\n    # Parse arguments\n    args = parser.parse_args()\n\n    train(\n        args,\n        pipeline_params.extract(args),\n        model_params.extract(args),\n        optimization_params.extract(args),\n        dataset_params.extract(args),\n    )\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "viewer.py",
    "content": "import numpy as np\nfrom PIL import Image\nimport configargparse\nimport warnings\n\nwarnings.filterwarnings(\"ignore\")\n\nimport torch\n\nfrom data_loader import DataHandler\nfrom configs import *\nfrom radfoam_model.scene import RadFoamScene\n\n\nseed = 42\ntorch.random.manual_seed(seed)\nnp.random.seed(seed)\n\n\ndef viewer(args, pipeline_args, model_args, optimizer_args, dataset_args):\n    checkpoint = args.config.replace(\"/config.yaml\", \"\")\n    device = torch.device(args.device)\n\n    test_data_handler = DataHandler(\n        dataset_args, rays_per_batch=0, device=device\n    )\n    test_data_handler.reload(split=\"test\", downsample=min(dataset_args.downsample))\n\n    # Define viewer settings\n    viewer_options = {\n        \"camera_pos\": test_data_handler.viewer_pos,\n        \"camera_up\": test_data_handler.viewer_up,\n        \"camera_forward\": test_data_handler.viewer_forward,\n    }\n\n    # Setting up model\n    model = RadFoamScene(\n        args=model_args, device=device, attr_dtype=torch.float16\n    )\n\n    model.load_pt(f\"{checkpoint}/model.pt\")\n\n    def viewer_init(viewer):\n        model.update_viewer(viewer)\n\n    model.show(viewer_init, **viewer_options)\n\n\ndef main():\n    parser = configargparse.ArgParser()\n\n    model_params = ModelParams(parser)\n    dataset_params = DatasetParams(parser)\n    pipeline_params = PipelineParams(parser)\n    optimization_params = OptimizationParams(parser)\n\n    # Add argument to specify a custom config file\n    parser.add_argument(\n        \"-c\", \"--config\", is_config_file=True, help=\"Path to config file\"\n    )\n\n    # Parse arguments\n    args = parser.parse_args()\n\n    viewer(\n        args,\n        pipeline_params.extract(args),\n        model_params.extract(args),\n        optimization_params.extract(args),\n        dataset_params.extract(args),\n    )\n\n\nif __name__ == \"__main__\":\n    main()\n"
  }
]